2

私はじゃんけんゲームをバッチで作ろうとしています。これまでのところ、スクリプトが実行され、それを自分自身と対戦させるか、自分と対戦させることができます (B var を /A と乱数から /P に変更し、ユーザー入力が必要です)。

問題は、数回 (毎回異なる量) のラウンドの後、スクリプトがクラッシュし、テキストの最後の行を読む時間がないことです (エラーを見つけるのに役立ちます)。ECHO ON と OFF を試してみました。また、別の DOS ウィンドウから (正しいディレクトリを選択して) 'RPS.bat >> log.txt' を実行しようとしました。クラッシュするまですべてをログに記録し、最後の行も取得しませんでした。

何度か調べましたが、エラーが見つかりません... :(

私は現在エラーなしでPHPで同じゲームを作成しました...(それはまったく異なる言語です、私は知っています)

だからここに私のスクリプトがあります:

@ECHO OFF
:TOP
SET /A AWON=0
SET /A BWON=0
SET /A NWON=0

:GAME
SET /A A=%RANDOM% %% 3 + 1
SET /P B=Number from 1 to 3

IF %A% EQU 1 (
    GOTO A1
) ELSE IF %A% EQU 2 (
GOTO A2
) ELSE IF %A% EQU 3 (
GOTO A3
) ELSE (
GOTO GAME
)

:A1
IF %B% EQU 1 (
GOTO DRAW
) ELSE IF %B% EQU 2 (
GOTO BWIN
) ELSE IF %B% EQU 3 (
GOTO AWIN
) ELSE (
    GOTO GAME
)

:A2
IF %B% EQU 1 (
    GOTO ARAW
) ELSE IF %B% EQU 2 (
    GOTO DRAW
) ELSE IF %B% EQU 3 (
    GOTO BWIN
) ELSE (
    GOTO GAME
)

:A3
IF %B% EQU 1 (
    GOTO BWIN
) ELSE IF %B% EQU 2 (
    GOTO AWIN
) ELSE IF %B% EQU 3 (
    GOTO DRAW
) ELSE (
    GOTO GAME
)

:AWIN
SET /A AWON=%AWON% + 1
ECHO -------------------------------------------------------------------------------
ECHO A won this round!
ECHO ---
ECHO A won: %AWON%
ECHO B won: %BWON%
ECHO Draw: %NWON%
PAUSE
GOTO GAME

:BWIN
SET /A BWON=%BWON% + 1
ECHO -------------------------------------------------------------------------------
ECHO B won this round!
ECHO ---
ECHO A won: %AWON%
ECHO B won: %BWON%
ECHO Draw: %NWON%
PAUSE
GOTO GAME

:DRAW
SET /A NWON=%NWON% + 1
ECHO -------------------------------------------------------------------------------
ECHO This round was a draw!
ECHO ---
ECHO A won: %AWON%
ECHO B won: %BWON%
ECHO Draw: %NWON%
PAUSE
GOTO GAME

私の愚かな間違いを助けてくれたグレイに感謝します^^

スクリプトにも感謝しますが、ここで何かが欠けていなければ、それは正しくありません。

@ECHO OFF
:GAME
SET /P A=A: 
SET /P B=B: 
SET /A WINNER=(%A%-%B%) %% 3
ECHO %A% - %B% = %WINNER%
IF %WINNER% EQU 1 (
    echo A WON! 
) ELSE (
IF %WINNER% EQU 0 (
    echo DRAW!
) ELSE (
    echo B WON!
))
PAUSE
GOTO GAME

そのスクリプト (グレイのスクリプトの「短縮」バージョン) を実行します。私の「テーブル」のように変数を使用すると、1 (ロック) を選択すると、A が勝つことができないことがわかります (A=1 対 B=3 は A が勝つはずです)。これを修正する方法について何か考えはありますか?「ハードコードされた?」と思います。A=1 と B=3 の場合の解が最適でしょうか? (つまり、これらの値の場合、「通常の」スクリプトは適用されませんが、代わりに特別なコードが結果を返します)。

私の表では、最後の記号が「+」の場合、スクリプトは正しい答えを返し、最後の記号が「-」の場合、スクリプトは間違った答えを返します。

ITEM     VALUE

ROCK     1
PAPER    2
SCISSORS 3

A - B = WINNER

1 - 1 =  0 DRAW  +
1 - 2 = -1 B WON +
1 - 3 = -2 A WON -
2 - 1 =  1 A WON +
2 - 2 =  0 DRAW  +
2 - 3 = -1 B WON +
3 - 1 =  2 B WON +
3 - 2 =  1 A WON +
3 - 3 =  0 DRAW  +

また、スクリプトをより整頓し、より少ない行数のコードを使用して同じ作業を行う方法についてのヒントがあれば、喜んで耳を傾けます!

前もって感謝します!- エスペン

4

1 に答える 1

3

あなたのエラーはおそらく次のように言っています:

指定されたバッチ ラベルが見つかりません - ARAW

これは、意図したように見えるときにGOTO ARAW、ラベルにあるためです。A2GOTO AWIN

ボーナス:勝者を決定するより「賢い」方法として(確実にもっと改善される可能性があります)

@echo off

rem rock:1; paper:2; scissors:3
:GAME
SET /A CPU=%RANDOM% %% 3 + 1
SET /P PLAYER=Number from 1 to 3
cls
echo %CPU% vs %PLAYER%

rem set /A WINNER=(%CPU%-%PLAYER%) %% 3 //this does not work with batch - my mistake
SET /A WINNER=(%CPU% - %PLAYER% + 3) %% 3

IF %WINNER% EQU 1 (
   echo CPU WON! 
) ELSE (
IF %WINNER% EQU 0 (
   echo DRAW!
) ELSE (
   echo YOU WON!
))

GOTO GAME

そして最後に、「じゃんけん」、「ペーパー」、「はさみ」を印刷して、もう少し楽しくしたものを紹介します。

@echo off

rem rock:1; paper:2; scissors:3
:GAME
SET /A CPU=%RANDOM% %% 3 + 1
SET /P PLAYER=Number from 1 to 3
goto CPUTYPE
:TYPE1
goto PLAYERTYPE
:TYPE2
cls
echo CPU:%CPUT% vs YOU:%PLAYERT%

rem set /A WINNER=(%CPU%-%PLAYER%) %% 3 //this does not work with batch - my mistake
SET /A WINNER=(%CPU% - %PLAYER% + 3) %% 3
IF %WINNER% EQU 1 (
    echo CPU WON! 
) ELSE (
IF %WINNER% EQU 0 (
    echo DRAW!
) ELSE (
    echo YOU WON!
))

GOTO GAME

:CPUTYPE
    IF %CPU% EQU 1 (
        SET CPUT="ROCK" 
    ) ELSE (
    IF %CPU% EQU 2 (
        SET CPUT="PAPER" 
    ) ELSE (
        SET CPUT="SCISSORS" 
    ))
    GOTO TYPE1

:PLAYERTYPE
    IF %PLAYER% EQU 1 (
        SET PLAYERT="ROCK" 
    ) ELSE (
    IF %PLAYER% EQU 2 (
        SET PLAYERT="PAPER" 
    ) ELSE (
        SET PLAYERT="SCISSORS" 
    ))
    GOTO TYPE2

asker の PvP バージョンに基づいて更新されたバージョン (固定モジュール

@ECHO OFF
:GAME
SET /P A=A: 
SET /P B=B: 
SET /A WINNER=(%A% - %B% + 3) %% 3
ECHO W= %WINNER%
IF %WINNER% EQU 1 (
    echo A WON! 
) ELSE (
IF %WINNER% EQU 0 (
    echo DRAW!
) ELSE (
    echo B WON!
))
PAUSE
GOTO GAME

の説明SET /A WINNER=(%CPU% - %PLAYER% + 3) %% 3:

2拍1、3拍2、1拍3。%or モジュラス演算子を使用してそれを行います。モジュラス演算子は、基本的に、整数除算を使用してその数で割った場合の余りを返します。

ここに 1 から 6 mod 3 があり、答えは太字で示されています。

1 / 3 = 0 レム1

2 / 3 = 0 レム2

3 / 3 = 1 レム0

4 / 3 = 1 レム1

5 / 3 = 1 レム2

6 / 3 = 2 レム0

結果が常に < 3 かつ > 0 であることに注意してください。このメカニズムを利用して、じゃんけんの円運動を模倣します。また、これらの例では +3 を行っていないことに気付いたかもしれません。+3 が追加されたのは、Microsoft がモジュラスを実装するために選択した方法であり、負の数がある場合に奇妙なことを行うためです (それが、あなたが見つけたバグを修正した方法です)。私は、符号が結果を変えないところに慣れていたのと同じように、モジュラスを使用すると想定していました。基本的に、演算を 3 シフトするだけなので、負になることはありません。この種のことについては、ここで詳しく読むことができます:循環バッファー。私は例が好きなので、ここに役立つものがあります。

ネクタイ:

1v1 -> (1 - 1 + 3) % 3 -> 3 % 3 -> 1 レム0

2v2 -> (2 - 2 + 3) % 3 -> 3 % 3 -> 1 レム0

3v3 -> (3 - 3 + 3) % 3 -> 3 % 3 -> 1 レム0

プレイヤー1勝

1v3 -> (1 - 3 + 3) % 3 -> 1 % 3 -> 0 レム1

2v1 -> (2 - 1 + 3) % 3 -> 4 % 3 -> 1 レム1

3v2 -> (3 - 2 + 3) % 3 -> 4 % 3 -> 1 レム1

プレーヤー 2 の勝利

1v2 -> (1 - 2 + 3) % 3 -> 2 % 3 -> 0 レム2

2v3 -> (2 - 3 + 3) % 3 -> 2 % 3 -> 0 レム2

3v1 -> (3 - 1 + 3) % 3 -> 5 % 3 -> 1 レム2

ここでのパターンは、すべての剰余 (モジュラス演算子の結果) がすべて一致するというものです。なんて都合のいい!これで、そのケースを if ステートメントに一致させるだけで、すべてのゲームで誰が勝ったかがわかります。

于 2013-07-12T18:42:13.530 に答える