如果 - 否则替代

时间:2009-03-18 22:28:32

标签: java arrays if-statement

我有一个我正在编写的程序,其工作原理是填充二维数组以检查获胜条件,它是noughts和crosses,所以只需点击一个按钮就可以填充二维数组,1代表一个圆圈, 2表示交叉,然后checkWin()将按照这个原则工作,而不是实际的代码...

if (myArray[0][0] == 1 && myArray[0][1] == 1 && myArray[0][2] == 1){
    setBoolWinVal = true;
} else {
    if(myArray[0][0] == 2 && myArray[0][1] == 2 && myArray[0][2] == 2){
    setBoolWinVal = true;
}

你可以立即看到,对于每一个获胜条件,这将是凌乱的,有没有办法重写这个检查获胜,以缩短它?

12 个答案:

答案 0 :(得分:7)

这看起来像是家庭作业,所以我不会完全放弃它。但请注意以下几点:

  • 当你连续三次,一列或一条对角线上有三个相同的东西时,你就赢了。

  • 这不是你需要检查一行中是否有三个零或三个十字架,而是一行中有三个相同的东西

您可以从编写一个函数开始,该函数确定行,列或对角线是否具有三种相同类型的东西(并且该东西不是空白单元格)。然后为每行,每列和对角线调用该函数一次。

答案 1 :(得分:3)

这是(未经测试的)代码。它当然不是生产质量:)

请注意其他答案的一些优化:

  1. 使用for-loops
  2. 我们检查相等的玩家值,而非特定玩家值
  3. 对角线胜利必须通过单元格[1] [1]
  4. int find_winner(int[][] arr) {
    
        // check rows
        for (int i = 0; i < 3; ++i) {
            int player = arr[i][0];
            if (player < 1) continue; // nb: prior version didn't check for empty cells
            if (arr[i][1] == player && arr[i][2] == player) return player;
        }
    
        // check cols
        for (int i = 0; i < 3; ++i) {
            int player = arr[0][i];
            if (player < 1) continue;
            if (arr[1][i] == player && arr[2][i] == player) return player;
        }
    
        // check diagonals
        int player = arr[1][1];
        if (player < 1) return -1;
    
        if ((arr[0][0] == player && arr[2][2] == player) ||
            (arr[2][0] == player && arr[0][2] == player)) return player;
    
        // no winner found
        return -1;
    }
    

答案 2 :(得分:2)

显而易见的方法是循环行,列或对角线中的3个元素并检查它们是否相同。

另一种方法是使用更紧凑的表示 - 例如,一个int,其中9个单元格每个由2位表示,或者两个短路,每个玩家一个。然后使用查找表或按位操作将状态映射到输赢。

如果单个位代表一个单元格,并且您有一个填充位,则每个玩家的磁贴都是3个十六进制数字0-7。

对角线是:

cells & 0x421 == 0x421
cells & 0x124 == 0x124

垂直线是:

cells & (cells>>4) & (cells>>8) != 0

水平线

cells & (cells>>1) & (cells>>2) != 0

使用类似的技术使用64位模式来表示国际象棋游戏中可能的移动。

答案 3 :(得分:1)

两个有趣的想法:(我假设基础1D数组因为它让生活更轻松。)

首先:对要测试的位置进行编码。就像你有一维数组描述你的领域一样:

diag[] = { { 0, 1, 2}, {3, 4, 5}, {6, 7, 8},
           { 0, 3, 6}, {1, 4, 7}, {2, 5, 8},
           { 0, 4, 8}, {6, 4, 2}};

然后循环遍历diag:对于它的每个元素,测试三个相应的字段(使用diag[i]作为字段数组的索引)。

第二:使用位域来表示您的字段。像java.util.BitSet。然后将解编码为像{1,1,1,0,0,0,0,0,0},{0,0,0,1,1,1,0,0,0}等位域。然后你可以测试(循环)if (field & solution[i] == solution[i])。对于第二个玩家,只需在if语句中使用!field

有趣,不是吗? p.s。:你可以用它来编写Java代码!

答案 4 :(得分:0)

做作业的气味。

小提示 - 用于循环,它适用于您想要的任何大小。如果您使用递归,则会获得奖励积分。

定义: 递归 - &gt;请参阅递归

答案 5 :(得分:0)

因此,如果您考虑一下,您正在检查以下条件:

www   xxx   xxx  wxx
xxx   www   xxx  xwx
xxx   xxx   www  xxw

w是要检查胜利的人,而x是要忽略的。

(0,0),(0,1),(0,2)是第一个正确解中“w”的位置。 1,0,1,1和1,2是第二个,等等。

这让我觉得它应该是数据而不是代码。 诀窍是,如何有效地输入和存储数据。

请注意,此数据开始看起来像您的数组索引。

所以,假设您有一系列“解决方案”,其中包含8 x,y对(每个都表示一个成功的解决方案组合)

然后你要做的就是迭代这个集合,提取三个x,y对并测试它们。所以它与你拥有的相似,但是在你有数字的地方使用变量。

if(myArray[x0][y0] == 2 && myArray[x1][y1] == 2 && myArray[x2][y2] == 2){
    win();

在迭代它时,索引变量将替换为数据的下一行。

由于您不想在获胜后报告损失,因此您将不得不稍微使用逻辑来确保您的循环停止,但这可能已经对家庭作业风格问题提供了太多帮助

答案 6 :(得分:0)

这听起来有点像家庭作业,但我会帮助解决行和列的简单问题,检查它们是否已满,对角线稍微硬一点,我还是留给你。 同样,我相信嵌套的for循环是最好的主意:

java.util.Arrays;

public yourClass{

public void findAnswer{

int initialVal = 0;

int copy = 0;

int column = 0;

boolean columnVal = true;

boolean rowVal = false;

for (int j = 0; j< myArray.length; j++){ //presuming myArray and myArray[] are same length

boolean firstRun = true;

    for (int i = 0; i <myArray.length; i++){

        initialVal = myArray[i][column];
        if (firstRun == true){
            copy = intialVal; //makes a copy for the first time, to compare
            firstRun = false;
        }
        if (intialVal != copy){
            columnVal = false; //realises this column isnt a full column i.e. 3 1's or 2's in column
            return;
        }else
            columnVal = true;

        }//end nested for loop

    rowVal = findRow(j); 
    if(rowVal = true)
    return;
}

public boolean findRow(int row){

    int[] tempRow1, tempRow2;
    Arrays.fill(tempRow1, 1); 
    Arrays.fill(tempRow2, 2); //fills temp arrays for comparison
    boolean answer = false;
    if (Arrays.equals(myArray[], tempRow1) || Arrays.equals(myArray[], tempRow2) //this tests either, || being logical OR
        answer = true;
    return answer;
}
}

n.b。这段代码没有经过测试,而且很快就被编码了,所以看起来不是很好,它可以很精致,而且我还没有实现对角线。 附:如果是家庭作业,可能最好在互联网上查找内容,并尝试自己解决,而不是通过要求其他人为你寻求帮助。

答案 7 :(得分:0)

  1. 在0..19683(3到9日)中将棋盘表示为int
  2. 预先制作胜出的董事会,并确定谁是每个董事会的赢家,也许是手工
  3. 在运行时查找预先计算的地图中的当前电路板

答案 8 :(得分:0)

对于n X n矩阵......

//Check all horizontal rows
for(i=0; i<n && !setBoolWinVal; i++) //row
{
    setBoolWinVal = true;
    for(j=0; j<n-1; j++)
    {
        if( myArray[i][j] != myArray[i][j+1] ) //column
        {
            setBoolWinVal = false;
            break;
        }
    }

    if(setBoolWinVal) declareWinner(myArray[i][0]);
}

//Check all vertical columns
if(!setBoolWinVal)
{
    for(i=0; i<n && !setBoolWinVal; i++) //column
    {
        setBoolWinVal = true;
        for(j=0; j<n-1; j++) //row
        {
            if( myArray[j][i] != myArray[j+1][i] ) 
            {
                setBoolWinVal = false;
                break;
            }
        }
    }

    if(setBoolWinVal) declareWinner(myArray[0][i]);
}


//Check forward diagonal
if(!setBoolWinVal)
{
    setBoolWinVal = true;
    for(i=0; i<n-1; i++)
    {
        if( myArray[i][i] != myArray[i+1][i+1])
        {
            setBoolWinVal = false;
            break;
        }
    }

    if(setBoolWinVal) declareWinner(myArray[0][0]);
}

//Check reverse diagonal
if(!setBoolWinVal)
{
    setBoolWinVal = true;
    for(i=0, j=n-1; i<n-1 && j>0; i++, j--)
    {
        if( myArray[i][j] != myArray[i+1][j-1])
        {
            setBoolWinVal = false;
            break;
        }
    }

    if(setBoolWinVal) declareWinner(myArray[0][n-1]);
}

答案 9 :(得分:0)

你也可以迭代地解决这个问题:

  1. 为每列,行和对角线生成每种标记类型的数组。初始化为零。
  2. 对于网格中的每个条目,如果它有标记,则递增该标记的相应列,行和对角线条目。
  3. 如果这些条目中的任何条目等于电路板的尺寸,则该标记胜出。

答案 10 :(得分:0)

一个简单而优雅的解决方案 - 您可以通过以下方式将数字1到9分配给您的电路板:

8 1 6
3 5 7
4 9 2

这个方块具有每行,每列和对角线的独特特征 总和为15,除非,否则无法从三个单元格获得15的总和 它们共用一行,一列或一条对角线。

对于每个玩家,你保留两个布尔数组:

boolean squarePairs[PAIRSMAXSUM+1];
boolean chosenSquares[NUMSQUARES+1];

其中PAIRSMAXSUM = 9 + 8且NUMSQUARES = 9

然后,您可以通过调用此功能轻松检查获胜动作:

boolean hasWon(int squareIndex) {
    return squarePairs[WINNINGSUM - squareIndex];
}

其中WINNINGSUM为15.如果该函数返回false,则通过调用此函数来更新布尔数组:

void update(int squareIndex) {
    for (int i = 1; i <= NUMSQUARES; i++) {
        if (chosenSquares[i]) {     {
            squarePairs[i + squareIndex] = true;
        }
    }
    chosenSquares[squareIndex] = true;
}


就这么简单!

答案 11 :(得分:-1)

如果数组长度相同,则以下内容应该有所帮助。

Arrays.equals(myArray[0], {1,1,1})

否则,编写一个循环遍历myArray[0]中所有值的函数。