Isaac
asked on
JavaScript - Chessboard
Hi Gurus,
I'm currently reading a book called "Eloquent JavaScript" and working on all the projects as well. In Chapter 2, I am stuck on an exercise I've been working on for about a week but I can't figure it out.
Here's the exercise:
Write a program that creates a string that represents an 88 grid, using
newline characters to separate lines. At each position of the grid there
is either a space or a “#” character. The characters should form a chess
board.
Passing this string to console.log should show something like this:
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
When you have a program that generates this pattern, define a variable
size = 8 and change the program so that it works for any size, outputting
a grid of the given width and height.
Here's my solution but it's just not coming out correctly.
http://codepen.io/isogunro/pen/dpvKJp?editors=1112
Any hint\help\suggestion\comme nts would be greatly appreciated.
I'm currently reading a book called "Eloquent JavaScript" and working on all the projects as well. In Chapter 2, I am stuck on an exercise I've been working on for about a week but I can't figure it out.
Here's the exercise:
Write a program that creates a string that represents an 88 grid, using
newline characters to separate lines. At each position of the grid there
is either a space or a “#” character. The characters should form a chess
board.
Passing this string to console.log should show something like this:
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
When you have a program that generates this pattern, define a variable
size = 8 and change the program so that it works for any size, outputting
a grid of the given width and height.
Here's my solution but it's just not coming out correctly.
http://codepen.io/isogunro/pen/dpvKJp?editors=1112
Any hint\help\suggestion\comme
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Actually, my code produced this. Not sure why b/c my loop is 8
" "
" #"
" # "
" # #"
" # # "
" # # #"
" # # # "
" # # # #"
" "
" #"
" # "
" # #"
" # # "
" # # #"
" # # # "
" # # # #"
" "
" #"
" # "
" # #"
" # # "
" # # #"
" # # # "
" # # # #"
" "
" #"
" # "
" # #"
" # # "
" # # #"
" # # # "
" # # # #"
" "
" #"
" # "
" # #"
" # # "
" # # #"
" # # # "
" # # # #"
" "
" #"
" # "
" # #"
" # # "
" # # #"
" # # # "
" # # # #"
" "
" #"
" # "
" # #"
" # # "
" # # #"
" # # # "
" # # # #"
" "
" #"
" # "
" # #"
" # # "
" # # #"
" # # # "
" # # # #"
" "
" #"
" # "
" # #"
" # # "
" # # #"
" # # # "
" # # # #"
" "
" #"
" # "
" # #"
" # # "
" # # #"
" # # # "
" # # # #"
" "
" #"
" # "
" # #"
" # # "
" # # #"
" # # # "
" # # # #"
" "
" #"
" # "
" # #"
" # # "
" # # #"
" # # # "
" # # # #"
" "
" #"
" # "
" # #"
" # # "
" # # #"
" # # # "
" # # # #"
" "
" #"
" # "
" # #"
" # # "
" # # #"
" # # # "
" # # # #"
" "
" #"
" # "
" # #"
" # # "
" # # #"
" # # # "
" # # # #"
" "
" #"
" # "
" # #"
" # # "
" # # #"
" # # # "
" # # # #"
ASKER
I think I see the problem...be back. stand by..
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
YES!!! I got it. Thanks for the hints gentleman. Now on to the next chapter, Functions.
var num = 8;
for (var i=1; i<=num; i++) {
var y="";
for (var x=1; x<=num; x++){
if(x%2===0){
y += "#";
}
else {
y += " ";
}
}
console.log(y);
}
ASKER
Much appreciated
Not exactly, cause:
and
Means you need one "print".. "this string" is singular. Thus you should use one print/output call.
You're currently using num prints.
Hint: How many prints do you think you need?
and
Passing this string to console.
Means you need one "print".. "this string" is singular. Thus you should use one print/output call.
You're currently using num prints.
Using pairs same result. Each row we just alternate what a square looks like ' #' then '# ';
<script>
var num = 8;
var cols = num / 2;
for(var row=1; row<=num;row++) {
var square = row % 2 ? ' #' : '# ';
var line = '';
for(var col=1;col<=cols;col++) {
line += square;
}
console.log(line);
}
</script>
num = 9?
granted
ASKER
ste5an,
I did use one print (console.log). Is that what you mean?
What's wrong with num=9? It produced the correct result.
http://codepen.io/isogunro/pen/dpvKJp?editors=1112
I did use one print (console.log). Is that what you mean?
What's wrong with num=9? It produced the correct result.
http://codepen.io/isogunro/pen/dpvKJp?editors=1112
ASKER
Nevermind...
Coding is a strict process. The requirements tell you that you should create one string and output this single string.
E.g.
And for a 9x9 board the correct output is the first, yours the second:
A chess board has an alternate coloring scheme and starts with a black square in the bottom, left corner.
E.g.
var outputCounter = 0;
var num = 9;
for (var i=1; i<=num; i++) {
var y="";
for (var x=1; x<=num; x++){
if(x%2===0){
y += "#";
}
else {
y += " ";
}
}
console.log(y);
outputCounter += 1;
}
console.log('Num outputs:' + outputCounter);
And for a 9x9 board the correct output is the first, yours the second:
A chess board has an alternate coloring scheme and starts with a black square in the bottom, left corner.
ASKER
Ahhhh.....I see. dang
A further hint: A "general" chess board is not necessarily squared, thus the task asks for working with independent width and height.
ASKER
hmmm......looks like I'm not done. Need to think some more.
BTW Julian, your code produced when I entered it in codepen
"####"
" # # # #"
"####"
" # # # #"
"####"
" # # # #"
"####"
" # # # #"
BTW Julian, your code produced when I entered it in codepen
"####"
" # # # #"
"####"
" # # # #"
"####"
" # # # #"
"####"
" # # # #"
Just start by building the board row by row.
Hint: sequence of pieces in a 4x4 board is (ATTENTION, ASCII ART :):
Hint: sequence of pieces in a 4x4 board is (ATTENTION, ASCII ART :):
+--+--+--+--+
|16|15|14|13|
+--+--+--+--+
| 9|10|11|12|
+--+--+--+--+
| 8| 7| 6| 5|
+--+--+--+--+
| 1| 2| 3| 4|
+--+--+--+--+
As you can rotate a chess board, try to output this:
And before doing this, print this:
4|3|2|1|
|5|6|7|8
12|11|10|9|
|13|14|15|16
And before doing this, print this:
|1|2|3|4
|5|6|7|8
|9|10|11|12
|13|14|15|16
ASKER
This is harder than I thought.
First of all start with the description of the problem:
This translates to pseudo-code using chess semantics:
board =''
foreach rank
line = 'build line'
board += line
print board
Then examine how to build a line. Either you can use the idea behind the square sequence or (another approach) use the visual approach: the second rank is the inverse of the first rank.
[..] using newline characters to separate lines. [..] Passing this string [..]
This translates to pseudo-code using chess semantics:
board =''
foreach rank
line = 'build line'
board += line
print board
Then examine how to build a line. Either you can use the idea behind the square sequence or (another approach) use the visual approach: the second rank is the inverse of the first rank.
ASKER
Why would I need the "\n" if the outer loop creates a new line already?
Well, where you place the add does not really matters. Whether it's alread at the end of the line or you do it in the outer loop, as long as it is added. The point is where do you know that the line is completed?
BTW Julian, your code produced when I entered it in codepenAre you sure you entered it incorrectly - here is a link to the code - check the output in the console.
The link return a blank page in Edge..
This might be jumping the gun on your learning path but there are some other techniques that can be used to solve this problem. The following is a discussion in thinking about the problem and how we can use what we know about the problem to derive a solution.
Lets look at what you are trying to achieve.
There are two possible output values a space ' ' and hash '#'
You are basically alternating between those.
The second consideration is that each odd row starts with the same character and each even row starts with the same character.
Rows can be odd or even. When even, the last character on the current row is the same as the starting character on the following row. But with odd rows the characters alternate across rows.
Example 2x2
The third consideration is the last row should always end in a space (if we follow the rule that a chessboard always has a white square in the bottom right hand corner)
Consider the grids above. Both of them satisfy this consideration. What do we notice about the first row in each case? In both cases the row starts with a space.
How can we use the information in the above considerations to solve the problem.
Instead of using if statements why don't we rather store the output characters in an array like so
We need k to alternate between the two squares on each output within a row i.e. k needs to flip between 1 and 0.
There is a neat trick to getting a variable to flip between 1 and 0
When k is 0 the result is 1
Using the above we can put the following together
We could therefore do this
We know the first row must start with a space, and we know that the space is index 1 in the square array so k must start at 1. In other words when
To complete our code we can therefore put an initialiser for k on each iteration of the outer loop like this
Lets look at what you are trying to achieve.
There are two possible output values a space ' ' and hash '#'
You are basically alternating between those.
The second consideration is that each odd row starts with the same character and each even row starts with the same character.
Rows can be odd or even. When even, the last character on the current row is the same as the starting character on the following row. But with odd rows the characters alternate across rows.
Example 2x2
| #|
|# |
If we flatten the above out we get| ## |
Example 3x3| # |
|# #|
| # |
If we flatten this one out we get| # # # # |
The third consideration is the last row should always end in a space (if we follow the rule that a chessboard always has a white square in the bottom right hand corner)
Consider the grids above. Both of them satisfy this consideration. What do we notice about the first row in each case? In both cases the row starts with a space.
How can we use the information in the above considerations to solve the problem.
Instead of using if statements why don't we rather store the output characters in an array like so
var square=['#',' '];
We need an index into this array - lets call it k.We need k to alternate between the two squares on each output within a row i.e. k needs to flip between 1 and 0.
There is a neat trick to getting a variable to flip between 1 and 0
k = 1 - k
When k is 1 the result is 0When k is 0 the result is 1
Using the above we can put the following together
var num = 8;
var square=['#', ' '];
for(var row=1; row<=num;row++) {
line = '';
for(var col=1; col<=num;col++) {
line += square[k];
k = 1 - k;
}
console.log(line);
}
This code is not quite ready yet. Firstly, we have not initialised k to a starting value. If we look at our discovery in the third consideration above we see that the first row must always start with a ' ' which means, given our square array k needs to start as a 1.We could therefore do this
var num = 8;
var square=['#', ' '];
var k = 1;
for(var row=1; row<=num;row++) {
line = '';
for(var col=1; col<=num;col++) {
line += square[k];
k = 1 - k;
}
console.log(line);
}
This is also still not quite there - if we run it for num = odd number it works - but for even numbers it just prints out N of the same row. This is because of what we found in the second consideration i.e. N = odd number characters alternate across rows, N = even number the last character of the current row is the same as the first character of the next. This means that we need to initialise k differently on each row. This is easily done. We already have the outer loop that is alternating between odd and even numbers - we can use that to initialise k. Whatever row N starts with row N + 1 must be the other character.We know the first row must start with a space, and we know that the space is index 1 in the square array so k must start at 1. In other words when
row = 1, k = 1
row = 2, k = 0
row = 3, k = 1
...
If you study the pattern of the above you will see it follows row modulus 2To complete our code we can therefore put an initialiser for k on each iteration of the outer loop like this
var num = 8;
var square=['#', ' '];
for(var row=1; row<=num;row++) {
line = '';
k = row % 2;
for(var col=1; col<=num;col++) {
line += square[k];
k = 1 - k;
}
console.log(line);
}
The link return a blank page in Edge..As it should - it is pure JavaScript to see the output you need to F12 and for Edge you need to refresh the page when the console is open. console is not available when the console window is not open.
If we want to stick to the exact requirements of the problem which is to separate lines with \n chars and have one output statement then we need to
a) Initialise line outside the loop
b) Remove the re-initialisation of the line in the loop
c) Terminate line with a \n at the completion of each inner loop
d) Move the console.log(line) outside both loops.
a) Initialise line outside the loop
b) Remove the re-initialisation of the line in the loop
c) Terminate line with a \n at the completion of each inner loop
d) Move the console.log(line) outside both loops.
<script>
var num = 8;
var square=['#', ' '];
// a) Initialise line outside the loop
var line = '';
for(var row=1; row<=num;row++) {
// b) Remove the re-initialisation of the line in the loop
// line = '';
k = row % 2;
for(var col=1; col<=num;col++) {
line += square[k];
k = 1 - k;
}
// c) Terminate line with a \n at the completion of each inner loop
line += '\n';
}
// d) Move the console.log(line) outside both loops.
console.log(line);
</script>
using the square sequence
var height = 8;
var width = 10;
var board = '';
for (var rank = 1; rank <= height; rank++) {
var line = '';
for (var file = 1; file <= width; file++ ) {
line = ((file + (rank % 2 === 0 ? 0 : 1)) % 2 === 0 ? '#' : '.') + line;
}
board += line + '\n';
}
console.log(board);
ASKER
Thanks Julian!
I need to dissect your scripts in chrome, especially the last one. The "\n" is throwing me off. I would think that the outerloop would cause the newline implicitly.
I need to dissect your scripts in chrome, especially the last one. The "\n" is throwing me off. I would think that the outerloop would cause the newline implicitly.
Wrong link. Use https://jsfiddle.net/52z0jyat/
I would think that the outerloop would cause the newline implicitly.If you are console.log()'ing on each iteration of the outer loop it would - but we are only doing the console.log() after all iterations of both loops are complete i.e. just 1 single console.log() of a long line with all the rows. Therefore the \n is needed to break those lines up.
The two samples show the two different approaches - the first does N console.log() output (1 for each row - so no \n is required) the second as a single output - which needs \n
The original question stated
Write a program that creates a string that represents an 8x8 grid, using newline characters to separate linesI also interpret the question to mean a square board rather than one allowing for a different height and width. They ask for a variable called size - not width and height, so diverging into code on how to handle non-square boards might be clouding the issue.
ASKER
Ahh...Ok. I see now.
When you have a program that generates this pattern, define a variableDoes imho not impose a constraint on width and height.. otherwise replace height and width by size.
size = 8 and change the program so that it works for any size, outputting
a grid of the given width and height.
Does imho not impose a constraint on width and height.. otherwise replace height and width by size.It is ambiguous but I put it down to bad phrasing. If they wanted variable width and height they would have probably said
"define variables width and height ..."
But they said size - one variable for me implies a square. Given the level of this teaching example and what it is trying to achieve I would not think that a non-square output would not be a requirement for this question - maybe a follow up question. This seems to be teaching about how to obtain a specific output (8x8) and then change to the generic (size x size)
Having said that - I would solve it like this - building on the above example
First we would need to define a row and col value to replace num.
We would need to replace the loop terminators with these values.
Finally, we need to change how we determine the start value for k in the outer loop.
Once that is correct the rest will follow.
There are 4 possible scenarios we need to look at
Rows: EVEN
Cols: EVEN
| x|
|x |
Rows: EVEN
Cols: ODD
|x_x|
| x |
Rows: ODD
Cols: EVEN
|x |
| x|
|x |
Rows: ODD
Cols:ODD
| x |
|x x|
| x |
To keep true to the white square bottom right we need a truth table of what character to start on for each of the aboveROWS COLS : RESULT
EVEN EVEN : 1
EVEN ODD : 0
ODD EVEN : 0
ODD ODD : 1
That looks like an XOR resultSo what if we set start to the following
var start = (rows % 2 ^ cols % 2);
That will give us the opposite of what we want i.eROWS COLS : RESULT
EVEN EVEN : 0
EVEN ODD : 1
ODD EVEN : 1
ODD ODD : 0
But this is ok because we can use the same trick we are using to flip k to flip start and we can start off by setting k to start flipped which will give us the required result.In other words in the outer loop we have
k = 1 - start;
start = k;
Because the XOR initialistion of start resulted in a 0 for an EVEN / EVEN pairing the result for the initialisation of k will be 1. After that the flip will ensure we stay on track.Putting it all together
<script>
// REPLACE num WITH totalrows AND totalcols
// PREFIX WITH total SO AS NOT TO CONFUSE
// WITH LOOP row / col
var totalrows = 3;
var totalcols = 3;
var square=['#', ' '];
var line = '';
// INTIALISE START WITH XOR OF MOD's
var start = (totalrows % 2 ^ totalcols % 2);
for(var row=1; row<=totalrows;row++) {
// INITIALISE k WITH INVERSE OF START
k = 1 - start;
// SET start FOR NEXT ITERATION
start = k;
// THE REST REMAINS THE SAME
for(var col=1; col<=totalcols;col++) {
line += square[k];
k = 1 - k;
}
line += '\n';
}
console.log(line);
</script>
ASKER
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
Question 2: (Here''s what my code produced)
" # # # #"
" "
" #"
" # "
" # #"
" # # "
" # # #"
" # # # "
" # # # #"
Question 3:
8x8
Still confused