オブジェクト指向?
この問題は、人が原点から歩くと考えると、数学を使わなくて済みます。これをPythonで考えると、こんなクラスを作りたくなります。
class cWalker: def __init__(self): self.x = 0 self.y = 0 self.v = 1 def value(self): return self.v def walk(self): if self.x < 0: if self.y < 0: ...
原点に対し右下にいたなら左へ動く、などと行動を書けばよいです。同じようなことをバッチファイルでできないでしょうか。
pというオブジェクトのxというプロパティはp_xとします。メソッドはcWalker_valueなどとします。こう決めれば書けると思いますが、さらにp_classにクラス名を格納しておくと、いろいろ面白いことができると思います。コンストラクタは、
call :new cWalker p
と呼ぶことにします。そうすると、
call :cWalker_cWalker p
が呼ばれて、pのクラス名と必要なプロパティが設定されます。一般には引数も設定できるとよりよいですね。ただ、shiftで%*が変わらないので効率よくは書けません。あるいは引数の数の上限決めるかです。
メソッドは、
call :method p value
と呼ぶと、p_classよりクラス名がわかって、
call :cWalker_value p
が呼ばれます。あとは地道にメソッドを実装するだけです。
@echo off setlocal enabledelayedexpansion set /a N = 1001 set /a M = %N% * 2 - 2 call :new cWalker p call :method p value set /a s = %ERRORLEVEL% for /L %%k in (1, 1, %M%) do ( call :method p walk call :method p value set /a s += !ERRORLEVEL! ) echo %s% exit /b 0 rem // call :new classname var :new set %2_class=%1 call :%1_%1 %2 exit /b 0 rem // call :method var methodname :method call set classname=%%%1_class%% call :%classname%_%2 %1 exit /b %ERRORLEVEL% :cWalker_cWalker set /a %1_x = 0 set /a %1_y = 0 set /a %1_v = 1 exit /b 0 :cWalker_value setlocal set /a v = "%1_v" exit /b %v% :cWalker_walk set /a x = "%1_x" set /a y = "%1_y" set /a v = "%1_v" if %x% LSS 0 ( if %y% LSS 0 ( set /a %1_y += -%y% * 2 set /a %1_v += -%x% * 2 ) else ( set /a %1_x += -%x% * 2 set /a %1_v += %y% * 2 ) ) else ( if %y% LSS 0 ( set /a %1_x += -%x% * 2 set /a %1_v += -%y% * 2 ) else ( set /a %1_x += 1 set /a %1_y += -%y% * 2 - 1 set /a %1_v += %x% * 2 + 2 ) ) exit /b 0