如何解决《Eloquent Javascript》中的“棋盘”问题?

9

我是一位新手程序员,正在学习 JavaScript。我已经完成了 Codecademy 的课程,并正在阅读《JavaScript 高级程序设计》。我花费了很长时间终于写出了一些代码,但它无法运行!我不确定我的方法是否正确,但我知道我想使用循环来跟踪通过打印 # 号网格的进度。

编写一个程序,创建一个表示 8x8 网格的字符串,使用换行符分隔每行。 在网格的每个位置上,要么是一个空格,要么是一个“#”字符。 这些字符应该形成一个象棋棋盘。 将此字符串传递给 console.log 应该显示如下内容:

 # # # #
# # # # 
 # # # #
# # # # 
 # # # #
# # # # 

下面是我的代码:

    var chessBoard = "";
    var size = 8;

    for (var lineCounter = 1; lineCounter < size; lineCounter++) { 

        if (lineCounter%2 === 0) { /

/if lineCounter is an even number
        for (var charCounter = 1; charCounter < size; charCounter++) {
            var evenOdd = (charCounter%2 === 0);
            switch (evenOdd) {
                case true:
                    (chessBoard += "#");
                    break;
                case false:
                    (chessBoard += " ");
                    break;
                }
            }                   
        }
    else { //if lineCounter is an odd number
        for (var charCounter = 1; charCounter < size; charCounter++) {
            var evenOdd = (charCounter%2 === 0);
            switch (evenOdd) {
                case true:
                    (chessBoard += " ");
                    break;
                case false:
                    (chessBoard += "#");
                    break;
            }
            }                       
        }   
    chessBoard += "\n";
    }
    console.log(chessBoard);

当前程序的输出如下所示:
# # # #
 # # # 
# # # #
 # # # 
# # # #
 # # # 
# # # #

经过一些尝试,我已经学到了很多东西,但现在我发现了一个错误——明显只有7x7的网格而不是我想要的8x8。我怀疑这与我的for循环中使用"<"有关,但不确定是否有更好的方法来解决这个问题,而不仅仅是添加一个额外的数字。


2
你的代码生成了什么输出?这与你期望的有何不同?(请在问题中包含你的输出。) - Greg Hewgill
1
换行符应该是\n而不是/n - Rick Hitchcock
32个回答

19

其实很简单,你需要创建两个循环,一个用于遍历每一行,另一个用于选择你想要输出到控制台的元素(空格或#)。

查看注释以获得解决方案

var size = 8; //this is the variable setting

var board = "";//this is the empty string we're going to add either ' ' , '#' or newline

for (var y = 0; y < size; y++) {   /*in the outer loop we add newline to seperate rows*/
  for (var x = 0; x < size; x++) {/*every inner loop rappresents a line, and alternatively it's adding either ' ' or '#' to the string that's being populated*/
    if ((x + y) % 2 == 0)
      board += " ";
    else
      board += "#";
  }
  board += "\n";
}

console.log(board);

我发现我的错误是最初在最后一个外部 for 循环中包含 console.log。这大大简化了事情。 - tsaiDavid
1
你创建一个字符串并打印一次... 如果保持简单,就更容易理解。 - maioman
3
为什么是 (x + y) 呢?如何理解这一部分? - user2734550
以上答案中的 (x+y) % 2 是用来检查 x 和 y 的加法结果是奇数还是偶数,并打印出空格 " "(即白色)或 "#"(即黑色)。 - SagarBhanu

8

jsFiddle演示

我是国际象棋的粉丝 :) 在国际象棋中,有一个规则叫做“白色在右侧”,这意味着我们国际象棋棋盘的第一个方格将是空格。之后,每当行和列之间存在奇数匹配时,就会交替出现。

var board = "";
for(var i = 0; i < 8; i++){
 for(var a = 0; a < 8; a++){
  board += (a % 2) == (i % 2) ? " " : "#";
 }
 board += "\n";
}

查看面板,现在显示一个8x8网格

console.log(board);

 # # # #
# # # # 
 # # # #
# # # # 
 # # # #
# # # # 
 # # # #
# # # # 

可以随意用 i 来代替行数或用 a 代替列数。或者两者都设为一个大小 :) 它仍然有效。例如,a < 20 将给出 20 列。

 # # # # # # # # # #
# # # # # # # # # # 
 # # # # # # # # # #
# # # # # # # # # # 
 # # # # # # # # # #
# # # # # # # # # # 
 # # # # # # # # # #
# # # # # # # # # # 

1
我喜欢“白在右”的规则,但最好加上这个规则是从观察者的角度来解释的(例如,您正在俯视棋盘)。底行是您的行(您的大件和小件放置的位置),底行最右侧的单元格必须是白色的,因为“白在右”。我还使用“皇后必须匹配颜色”的规则来确定每个玩家的国王和皇后的位置。 - Stijn de Witt

6

这里有一种不同的方法。

每一行都有四个实例,要么是_#,要么是#_(其中下划线代表一个空格)。

偶数行以_#开头,奇数行以#_开头:

var chessBoard= '',
    size= 8,
    c;

for(var i = 0 ; i < size ; i++) {
  c= i%2 ? '# ' : ' #';
  for(var j = 0 ; j < size/2 ; j++) {
    chessBoard+= c;
  }
  chessBoard+= '\n';
}

console.log(chessBoard);


1
Rick,谢谢你的代码!我实际上非常喜欢将空格与#合并简化的这个想法。但是,我需要能够通过更改“size”变量来重用该程序。 - tsaiDavid
1
我的原始代码中省略了size,但现在我已经添加了它。现在运行得更好了吗? - Rick Hitchcock
Rick,那个解决了问题!请原谅我的无知,第3行中,您只是声明了一个空变量c吗?我对这一切都很新,但已经注意到您使用三元运算符来简化if/else。太棒了!编辑:此外,我了解到在这里使用模数:i%2会导致一个true/false值,然后从冒号的左侧或右侧进行选择。我原本以为模数运算符返回余数... - tsaiDavid
1
是的,我声明了变量 c 以在循环中使用。并且你对三元运算符(也称为条件运算符)的使用很好。 - Rick Hitchcock
1
Rick, 非常感谢 - 学到了很多。对我的最后一条评论进行了最后一分钟的编辑,涉及到模运算会产生余数的问题。 - tsaiDavid
1
i%2 中,取模运算确实会返回除以 2 后的余数(即 1 或 0),JavaScript 将其解释为 truefalse。(在 JavaScript 中,所有非零数字都被视为 true。) - Rick Hitchcock

2

这里是一个版本

console.log((new Array(65).join().split("")).map( function(v,i) {
    return ( (i/8 >> 0 ) % 2 ? ( i%2 ? " " : "#") : (i%2 ? "#" : " ") ) +
           ( (i+1) %8 ? "" : "\n" );
}).join(""));

1
var chessBoard = "";
var size = 8;

for (var lineCounter = 1; lineCounter < size; lineCounter++) { 

    if (lineCounter%2 === 0) { //if lineCounter is an even number
        for (var charCounter = 1; charCounter < size; charCounter++) {
            var evenOdd = (charCounter%2 === 0);
            switch (evenOdd) {
                case true:
                    chessBoard += "#";
                    break;
                case false:
                    chessBoard += " ";
                    break;
                }
            }                   
        }
    else { //if lineCounter is an odd number
        for (var charCounter = 1; charCounter < size; charCounter++) {
            var evenOdd = (charCounter%2 === 0);
            switch (evenOdd) {
                case true:
                    chessBoard += " ";
                    break;
                case false:
                    chessBoard += "#";
                    break;
            }
        }                       
    }   
    chessBoard += "\n";
}
console.log(chessBoard);

1
这将以#字符而不是空格开始第一行,因此与OP所请求的输出不完全匹配。 - DrCord

1

在《JavaScript编程精解》这本书中,仅凭目前提供的知识,这是我的解决方案:

   var board = "";
   var size = 8;

   // Outer for loop creates a new line** after each cycle of the inner for loop
   for (var lineCount = 0; lineCount < size; lineCount++) {
       //The nested for loop adds a character to the board variable on a single line proportional to the size variable
       for (var spaceCount = 0; spaceCount < size; spaceCount++) {
           //This if statement creates the offset lines in the example image by alternating the first character depending on the lineCount
           if (lineCount % 2 == 0) {
               var black = "#",
                   white = " ";
           } else {
               black = " ";
               white = "#";
           }
           if (spaceCount % 2 == 0) {
               board += white;
           } else {
               board += black;
           }
       }
       board += "\n"; //** new line created
   }
   console.log(board);

0

这里是另一个简化版本:

function chessBoard(symbol, gridSize) {
    gridSize = gridSize || 8;
    symbol=symbol || "#";
    let pattern = "";
    for (let i = 0; i < gridSize/2; i++)
        pattern += symbol + " ";//Forming the pattern

    for (let i = 0; i < gridSize; i++) {

        if (i % 2 === 0) {
            console.log(pattern);
        }
        else {
            console.log(" " + pattern) //For even rows adding the space in front
        }
    }
}
chessBoard('#',8);

0

虽然不是最优雅的解决方案,但它能够工作。

let chessBoard = "";
const boardSize = 8;

for (let yAxis = 0; yAxis < boardSize; yAxis++) {
  for (let xAxis = 0; xAxis < (boardSize / 2); xAxis++) {
    if (yAxis % 2 === 0) {
      chessBoard += " ";
      chessBoard += "#";
    }
    else {
      chessBoard += "#";
      chessBoard += " ";
    }
  }
  chessBoard += "\n";
}
console.log(chessBoard)

0

let num = prompt("choose area of board"); // gets input to determine board size.
rowString = "";
for (let height = 0; height < num; height++){ // sets board height
  for(let width = 0; width < num; width++){ // sets board width
    if ((height+width) % 2 == 0){ // alternates chars by row & height position
      rowString += "# ";
    }
    else{
      rowString += "  ";
    }
  }
  rowString += "\n"; // after 'num' chars added to row, add new line to board
}
console.log(rowString);

第5行的(height+row) % 2 == 0很重要,因为它决定了基于高度和行值是否将“ ”或#添加到rowString。如果仅基于高度,您将获得#'s和“ ”的交替,或者如果仅基于宽度,则会获得“ ”和#的交替。如果考虑第一个点; 高度0宽度0,它将计算为偶数,高度1宽度1,奇数等等..下一行高度1宽度0,奇数等等...这确保了您的棋盘是可扩展的。


0

我尝试使用while循环和对书中解决方案的基本理解。

var board = ""
var size = 8
var x = 0
var y = 0

while (x < size) //restricts number of rows "size" times
  {
    while (y < size) //changes value of board to board+= # or " " a combined "size" times restricting columns to "size"
     {
         if ((x+y) % 2 == 0) //adding x+y ensures each row begins with altering #/_
            board += " "; //increases value of board by _
         else
            board += "#"; //increases value of board by _
         y++; // increases from 0-8 allowing loop to execute 8 times.
     }
    board += "\n";
    x++; // increases from 0-8 allowing loop to execute 8 times.
    y = 0; //resets vaule of y to 0 to allow inner loop to repeate
  }

console.log(board) // board prints as a repeating string of #_ using line breaks to create new rows

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接