0
  • チェッカーボードゲームは11x11のマトリックスです。
  • ピースは白、黒、(1)ホワイトキング
  • 相手を挟んで駒を「捕まえる」ことができる
    • 例)黒い部分は、その左右または上下に白い部分/白い王があります
  • ボードの端または4つのコーナーピースのいずれかを使用してサンドイッチおよびキャプチャすることもできます
    • 例)ボードの左端にある白い部分、次に黒い部分が白い部分の右側に直接移動します。これはキャプチャになります

これまでのところ私は

  • 11x11マトリックス
  • (int)0 =空、1 =白、2 =黒、3=ホワイトキング

これまでの私のアルゴリズムは基本的なものです。上/下/左/右をチェックし、反対の場合は、その隣のピースが友好的なピースであるかどうかを確認し、そうである場合はキャプチャします。

しかし、それを単純に行うことはできません。ピースが2つの外縁の行または列にある場合、上記のアルゴリズムを使用すると、ArrayOutofBoundsExceptionエラーが発生するためです。

それから私は作品が白か黒かについての巨大なifステートメントを持っています。

これを最適化するもっと簡単な方法があるように感じます。そして、初心者のプログラマーとして、私はそれを見ることができません。誰かが何かを提案できますか?

以下の私のコードを見ると、これは移動が外側の端にある場合にのみ発生することがわかります...それが「1」列/行にある場合は、ほとんどすべてを再コピーして貼り付ける必要があります。 。その後、ArrayOutofBoundsExceptionを気にすることなく、最終的に2つのスペースを上/左/右/下にチェックできます。

次に、Black Piecesに対してすべてをやり直す必要があります。私のコードは本当にずさんなように見え、これを行う簡単な方法があると感じています。助言がありますか?

void makeMove(int typePiece, int fromRow, int fromCol, int toRow, int toCol) {
    board[toRow][toCol] = board[fromRow][fromCol];
    board[fromRow][fromCol] = EMPTY;        

    //CAPTURE
    if(typePiece == WHITE) {
        if(toRow==0) { //top row
            //check right
            if(toCol!=9 && board[toRow][toCol+1]==BLACK && 
                    (toCol==10 || board[toRow][toCol+2]==WHITE || board[toRow][toCol+2]==WHITEKING)) {
                board[toRow][toCol+1]=EMPTY;
            }
            //check left
            if(toCol!=1 && board[toRow][toCol-1]==BLACK && 
                    (toCol==0 || board[toRow][toCol-2]==WHITE || board[toRow][toCol-2]==WHITEKING)) {
                board[toRow][toCol-1]=EMPTY;
            }
            //check bottom
            if(board[toRow-1][toCol]==BLACK && (board[toRow-2][toCol]==WHITE || board[toRow-2][toCol]==WHITEKING)) {
                board[toRow-1][toCol]=EMPTY;
            }
        }
        else if(toRow == 10) { //bottom row
            //check right
            if(toCol!=9 && board[toRow][toCol+1]==BLACK && (toCol==10 || board[toRow][toCol+2]==WHITE || board[toRow][toCol+2]==WHITEKING)) {
                board[toRow][toCol+1]=EMPTY;
            }
            //check left
            if(toCol!=1 && board[toRow][toCol-1]==BLACK && (toCol==0 || board[toRow][toCol-2]==WHITE || board[toRow][toCol-2]==WHITEKING)) {
                board[toRow][toCol-1]=EMPTY;
            }
            //check top
            if(board[toRow+1][toCol]==BLACK && (board[toRow+2][toCol]==WHITE || board[toRow+2][toCol]==WHITEKING)) {
                board[toRow+1][toCol]=EMPTY;
            }
        }
        else if(toCol == 0) { //left column
            //check right
            if(board[toRow][toCol+1]==BLACK && (board[toRow][toCol+2]==WHITE || board[toRow][toCol+2]==WHITEKING)) {
                board[toRow][toCol+1]=EMPTY;
            }
            //check top
            if(toRow!=1 && board[toRow+1][toCol]==BLACK && (board[toRow+2][toCol]==WHITE || board[toRow+2][toCol]==WHITEKING)) {
                board[toRow+1][toCol]=EMPTY;
            }
            //check bottom
            if(toRow != 9 && board[toRow-1][toCol]==BLACK && (board[toRow-2][toCol]==WHITE || board[toRow-2][toCol]==WHITEKING)) {
                board[toRow-1][toCol]=EMPTY;
            }
        }
        else if(toCol == 10) { //right column
            //check left
            if(board[toRow][toCol-1]==BLACK && (toCol==0 || board[toRow][toCol-2]==WHITE || board[toRow][toCol-2]==WHITEKING)) {
                board[toRow][toCol-1]=EMPTY;
            //check top
            if(toRow!=1 && board[toRow+1][toCol]==BLACK && (board[toRow+2][toCol]==WHITE || board[toRow+2][toCol]==WHITEKING)) {
                board[toRow+1][toCol]=EMPTY;
            }
            //check bottom
            if(toRow != 9 && board[toRow-1][toCol]==BLACK && (board[toRow-2][toCol]==WHITE || board[toRow-2][toCol]==WHITEKING)) {
                board[toRow-1][toCol]=EMPTY;
            }
        }
4

3 に答える 3

1

あるピースは、別のピースの動きの結果としてのみキャプチャできると考えてください。黒い部分に隣接する場所に移動する白い部分があるとします(「私の隣に黒い部分がありますか?」の8つのチェック)。その時点で、同じ線に沿って向かいに白い部分があるかどうかを確認します(黒い部分が最初の白い部分の下にある場合は、最初の黒い部分の真下に別の白い部分があるかどうかを確認します。黒い部分が斜め上にある場合は、右側で、黒い部分の右側にある別の白い部分を確認します。など)。また、ピースが移動するたびにチェックする必要があります。a)私の周りに敵のピースがあり、その場合b)反対側に別の敵のピースがミラーリングされていますか?

これらの線に沿って何かを試してください:

for all eight directions (up, down, left, right, and the four diagonals):
    is there an enemy piece in that direction adjacent to me?
    if so:
        is there a friendly piece in that direction that is also adjacent to that enemy piece?
        if so:
             remove that piece

for all eight directions:
    is there an enemy piece in that direction adjacent to me?
    if so:
         is there another enemy piece in the opposite direction that is also adjacent to me?
    if so:
         remove me
于 2012-07-05T03:37:33.747 に答える
1

あなたの問題は「Go」ゲームと非常に似ているようです。

あなたができることは、「自由」と呼ばれるものをチェックすることです。自由は、作品のグループの隣にある自由な場所です。グループに(対戦相手に囲まれた)自由がなくなった場合、そのグループは死亡します。

これを実装する方法に関するヒントをいくつか示します。

ピースが移動するとき、あなたはその隣人をチェックします。隣人の一人が対戦相手の場合、

function: hasPieceLiberty(Position piece): return true if one of the neighbours is empty

function: hasGroupLiberty(Position currentPiece):
   add current piece to visited pieces for this group
   if currentPiece.hasPieceLiberty -> return true
   else 
       if currentPiece has no more non visited neighbours for this group -> return false
       else call hasGroupLiberty for non visited neighbours in the group

function: move(Position piece)
   if piece has neighbours that are opponents, check if opponent group has liberties

お役に立てば幸いです

編集:あなたの問題は、私が最初に考えたものよりも実際には単純であることに気づきました。単に線の脇だけでなく、どこでも相手を囲む必要があると思いました。次に、CosmicComputerの提案を確認する必要があります

于 2012-07-05T03:47:50.750 に答える
0

これを解決しようとしたときに、いくつかのカスタムアイテムがコードのクリーンアップに役立ちました。

structPoint'x'と'y'を取ります。2D配列の内容をマッピングするのに便利です。'x'値と'y'値を別々に操作する加算、減算など
Operationsを含めることができます。 チェックは、ポイントが配列の有効なインデックスであるかどうかを判断するのに役立ちます(パラメーターとして配列が指定されている場合)。オーバーライドもいいです。
isValidToString()

ソースポイント(、、など)からのすべての目的の方向を保持するポイントの配列は、その周囲にあるものを確認するのに最適です。提供された指示を繰り返します:[ ]。を回避するために位置の内容をチェックする前に、ポイントが配列の外側にあるかどうかを判断するために使用します。dir4dir8foreach( Point dir in dir4 ){ testPoint = sourcePoint + dir; ... }isValidIndexOutOfBoundsException

于 2012-07-18T14:28:46.983 に答える