Draw a checkerboard in Java

I’m reading through a programming book and am having trouble understanding a few parts of this code. The program draws a checkerboard, and colors the odd squares black.

import acm.graphics.*;
import acm.program.*;

public class CheckerBoard extends GraphicsProgram   {

public void run()   {
    double squareSize = (double) getHeight() / numRows;
    for(int i = 0; i <= numRows; i++){
        for(int j = 0; j <= numColumns; j++)    {
            double x = j * squareSize;
            double y = i * squareSize;
            GRect square = new GRect(x,y,squareSize,squareSize);
            square.setFilled((i + j) % 2 != 0);
            add(square);
        }
    }
}

private static final int numRows = 8;
private static final int numColumns = 8;

I understand most of the code, but I am still a little confused.

My first question is: How exactly does the program go through the for loops? They are nested, so would it create all of the columns (the j for loop) first? Or does it increment both i and j after the block of code finishes?

Secondly, why do I set x = j, and y = i? x is horizontal and j is vertical, shouldn’t I set x = i and y = j? Both seem to yield the same results.

Mostly, I would just like to know how the for loop runs each time around. a basic run or two through the program.

Any help would be appreciated, thanks!

6

My first question is: How exactly does the program go through the for loops? They are nested, so would it create all of the columns (the j for loop) first? Or does it increment both i and j after the block of code finishes?

Neither, really. Nested loops like this do not increment at the same time: the inner loop will run until j violates the condition (j > numColumns), then the i loop (the outer loop) will increment and the whole inner loop will run again. Also, as @JayElston said, only one square is drawn at a time. What this means is that on each run through the inner loop the program draws one row of squares, one in each column. The outer loop repeatedly draws these rows to create the whole checkerboard. So the idea is that the inner loop does not draw whole columns, but rather the part of each column that is in the row currently being worked on.

Secondly, why do I set x = j, and y = i? x is horizontal and j is vertical, shouldn’t I set x = i and y = j? Both seem to yield the same results.

As far as the x=j and y=i, what you’ve written isn’t quite accurate. x is actually set to j times the width of a square, and y is set to i times the width of a square. So if we’re on the fourth column, we are four squares horizontally from the starting point, and thus four times the width of a square in the x-direction from the edge. The fact that both yield the same results is a coincidence; it only happens because the checkerboard is square. Change numRows to 15 and run the program, then flip-flop them and run it again and you should see the difference. The first time, the number of rows will be 15 (or 16 if you’ve written the program with <= in the for loops), as expected from the variable name. But when x=i*squareSize, the number of columns will be 15. Note that x and y are positions at which to draw the squares, not the numbers of the rows and columns. That may make it make more sense.

Mostly, I would just like to know how the for loop runs each time around. a basic run or two through the program.

Something that might help would be to include the line System.out.println("i:"+i+"; j:"+j+"; x:"+x+"; x:"+y); in the inner loop right after GRect square…. (as I’ve demonstrated in my code below) In Java, System.out.println will show things on the console. Putting in that line will make the program spit out a line each time it draws a square, giving the values of i, j, x, and y.

Finally, here’s an expanded version of the program with lots of comments. It also tells you about its progress, which hopefully will help you see what’s happening. Note that I wouldn’t normally use multiline comments (/*...*/) anywhere near this much.

import acm.graphics.GLabel;
import acm.graphics.GRect;
import acm.program.GraphicsProgram;

public class CheckerBoard extends GraphicsProgram {

  public void run() {
    double squareSize = (double) getHeight() / numRows;

    /*
     * Make a variable to carry the number of the square
     * that's being made. So, the first square will be
     * number 0, the second will be number 1, etc.
     */
    int num = 0;

    /*
     * Run the contents once for each number between 0 and
     * numRows Note the < and not <=. Because we're starting
     * from 0, we need to use <. For example, suppose we
     * wrote int i=0; i<=1; i++. We would get our loop run
     * once with i=0 and once with i=1 before i would not be
     * <= 1. Since our numbers in this case are supposed to
     * be the number of rows, we don't want to loop after we
     * do the one before our numRows or numColumns
     */
    for (int i = 0; i < numRows; i++) {
      /*
       * Run the contents of this loop once for each number
       * between 0 and numColumns, including 0, not
       * including numColumns.
       */
      for (int j = 0; j < numColumns; j++) {
        /*
         * Calculate the position for the next square. If
         * we're in column 4, then the next square should be
         * at 4*(the width of each square).
         */
        double x = j * squareSize;
        double y = i * squareSize;

        /*
         * Create a square that's to be put at our x and y
         * positions calculated just above. Make its width
         * squareSize and its height squareSize.
         */
        GRect square = new GRect(x, y, squareSize, squareSize);

        /*
         * Make some text that will be put down. Use the
         * current value of num for its text
         * (Integer.toString just makes that integer into
         * text), and put it at the x-position we're working
         * with plus 1/4 of a squareSize and the y-position
         * we're working with plus 3/4 of a square. This
         * fakes centering the text in the squares.
         */
        GLabel label = new GLabel(Integer.toString(num), x + squareSize * .25,
            y + squareSize * .75);

        /*
         * Tell the user what our i, j, x, y, and num values
         * are.
         */
        System.out.println("i:" + i + "; j:" + j + "; X:" + x + "; Y:" + y
            + "; num: " + num);

        square.setFilled((i + j) % 2 != 0);
        add(square);

        /*
         * Stick that label on the page, just like with the
         * square.
         */
        add(label);

        /*
         * Increment the number variable (add one to it) so
         * the next square is num+1 (if this is square 0,
         * then the next one should be square 1)
         */
        num++;
      }
    }
  }

  // Change this to make the checkerboard non-square.
  private static final int numRows = 8;
  private static final int numColumns = 8;
}

And here’s what I get on my console when I run it:

i:0; j:0; X:0.0; Y:0.0; num: 0
i:0; j:1; X:25.0; Y:0.0; num: 1
i:0; j:2; X:50.0; Y:0.0; num: 2
i:0; j:3; X:75.0; Y:0.0; num: 3
i:0; j:4; X:100.0; Y:0.0; num: 4
i:0; j:5; X:125.0; Y:0.0; num: 5
i:0; j:6; X:150.0; Y:0.0; num: 6
i:0; j:7; X:175.0; Y:0.0; num: 7
i:1; j:0; X:0.0; Y:25.0; num: 8
i:1; j:1; X:25.0; Y:25.0; num: 9
i:1; j:2; X:50.0; Y:25.0; num: 10
i:1; j:3; X:75.0; Y:25.0; num: 11
i:1; j:4; X:100.0; Y:25.0; num: 12
i:1; j:5; X:125.0; Y:25.0; num: 13
i:1; j:6; X:150.0; Y:25.0; num: 14
i:1; j:7; X:175.0; Y:25.0; num: 15
i:2; j:0; X:0.0; Y:50.0; num: 16
i:2; j:1; X:25.0; Y:50.0; num: 17
i:2; j:2; X:50.0; Y:50.0; num: 18
i:2; j:3; X:75.0; Y:50.0; num: 19
i:2; j:4; X:100.0; Y:50.0; num: 20
i:2; j:5; X:125.0; Y:50.0; num: 21
i:2; j:6; X:150.0; Y:50.0; num: 22
i:2; j:7; X:175.0; Y:50.0; num: 23
i:3; j:0; X:0.0; Y:75.0; num: 24
i:3; j:1; X:25.0; Y:75.0; num: 25
i:3; j:2; X:50.0; Y:75.0; num: 26
i:3; j:3; X:75.0; Y:75.0; num: 27
i:3; j:4; X:100.0; Y:75.0; num: 28
i:3; j:5; X:125.0; Y:75.0; num: 29
i:3; j:6; X:150.0; Y:75.0; num: 30
i:3; j:7; X:175.0; Y:75.0; num: 31
i:4; j:0; X:0.0; Y:100.0; num: 32
i:4; j:1; X:25.0; Y:100.0; num: 33
i:4; j:2; X:50.0; Y:100.0; num: 34
i:4; j:3; X:75.0; Y:100.0; num: 35
i:4; j:4; X:100.0; Y:100.0; num: 36
i:4; j:5; X:125.0; Y:100.0; num: 37
i:4; j:6; X:150.0; Y:100.0; num: 38
i:4; j:7; X:175.0; Y:100.0; num: 39
i:5; j:0; X:0.0; Y:125.0; num: 40
i:5; j:1; X:25.0; Y:125.0; num: 41
i:5; j:2; X:50.0; Y:125.0; num: 42
i:5; j:3; X:75.0; Y:125.0; num: 43
i:5; j:4; X:100.0; Y:125.0; num: 44
i:5; j:5; X:125.0; Y:125.0; num: 45
i:5; j:6; X:150.0; Y:125.0; num: 46
i:5; j:7; X:175.0; Y:125.0; num: 47
i:6; j:0; X:0.0; Y:150.0; num: 48
i:6; j:1; X:25.0; Y:150.0; num: 49
i:6; j:2; X:50.0; Y:150.0; num: 50
i:6; j:3; X:75.0; Y:150.0; num: 51
i:6; j:4; X:100.0; Y:150.0; num: 52
i:6; j:5; X:125.0; Y:150.0; num: 53
i:6; j:6; X:150.0; Y:150.0; num: 54
i:6; j:7; X:175.0; Y:150.0; num: 55
i:7; j:0; X:0.0; Y:175.0; num: 56
i:7; j:1; X:25.0; Y:175.0; num: 57
i:7; j:2; X:50.0; Y:175.0; num: 58
i:7; j:3; X:75.0; Y:175.0; num: 59
i:7; j:4; X:100.0; Y:175.0; num: 60
i:7; j:5; X:125.0; Y:175.0; num: 61
i:7; j:6; X:150.0; Y:175.0; num: 62
i:7; j:7; X:175.0; Y:175.0; num: 63

3

The double for-loop is essentially the same as this code:

int i = 0;

while (i <= numRows) {
    int j = 0;

    while (j <= numColumns) {
        double x = j * squareSize;
        double y = i * squareSize;
        GRect square = new GRect(x,y,squareSize,squareSize);
        square.setFilled((i + j) % 2 != 0);
        add(square);

        j++;
    }

    i++;
}

There is one small difference: at the end of the outer while-loop, i will have the value numRows + 1. If you use the for-loop the variable i will be out of scope.

Each time through the inner loop, a single board square is drawn (by adding it to the board). The following three lines of code draw the square:

GRect square = new GRect(x,y,squareSize,squareSize);
square.setFilled((i + j) % 2 != 0);
add(square);

(x,y) in the first line specify the upper left coordinate of the square to be drawn.

The second line determines the square color. As the inner and outer loops iterate, the value of i+j alternates between even and odd.

The squares are added in column order. After one full cycle of the inner loop, a new row of eight squares will be added.

The outer loop iterates once for each row, cycling through the inner loop to add the row.

A for loop is perhaps the most commonly used form of iteration. This loop performs initialization before the first iteration. Then it performs conditional testing and, at the end of each iteration, some form of “stepping.”

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

Draw a checkerboard in Java

I’m reading through a programming book and am having trouble understanding a few parts of this code. The program draws a checkerboard, and colors the odd squares black.

import acm.graphics.*;
import acm.program.*;

public class CheckerBoard extends GraphicsProgram   {

public void run()   {
    double squareSize = (double) getHeight() / numRows;
    for(int i = 0; i <= numRows; i++){
        for(int j = 0; j <= numColumns; j++)    {
            double x = j * squareSize;
            double y = i * squareSize;
            GRect square = new GRect(x,y,squareSize,squareSize);
            square.setFilled((i + j) % 2 != 0);
            add(square);
        }
    }
}

private static final int numRows = 8;
private static final int numColumns = 8;

I understand most of the code, but I am still a little confused.

My first question is: How exactly does the program go through the for loops? They are nested, so would it create all of the columns (the j for loop) first? Or does it increment both i and j after the block of code finishes?

Secondly, why do I set x = j, and y = i? x is horizontal and j is vertical, shouldn’t I set x = i and y = j? Both seem to yield the same results.

Mostly, I would just like to know how the for loop runs each time around. a basic run or two through the program.

Any help would be appreciated, thanks!

6

My first question is: How exactly does the program go through the for loops? They are nested, so would it create all of the columns (the j for loop) first? Or does it increment both i and j after the block of code finishes?

Neither, really. Nested loops like this do not increment at the same time: the inner loop will run until j violates the condition (j > numColumns), then the i loop (the outer loop) will increment and the whole inner loop will run again. Also, as @JayElston said, only one square is drawn at a time. What this means is that on each run through the inner loop the program draws one row of squares, one in each column. The outer loop repeatedly draws these rows to create the whole checkerboard. So the idea is that the inner loop does not draw whole columns, but rather the part of each column that is in the row currently being worked on.

Secondly, why do I set x = j, and y = i? x is horizontal and j is vertical, shouldn’t I set x = i and y = j? Both seem to yield the same results.

As far as the x=j and y=i, what you’ve written isn’t quite accurate. x is actually set to j times the width of a square, and y is set to i times the width of a square. So if we’re on the fourth column, we are four squares horizontally from the starting point, and thus four times the width of a square in the x-direction from the edge. The fact that both yield the same results is a coincidence; it only happens because the checkerboard is square. Change numRows to 15 and run the program, then flip-flop them and run it again and you should see the difference. The first time, the number of rows will be 15 (or 16 if you’ve written the program with <= in the for loops), as expected from the variable name. But when x=i*squareSize, the number of columns will be 15. Note that x and y are positions at which to draw the squares, not the numbers of the rows and columns. That may make it make more sense.

Mostly, I would just like to know how the for loop runs each time around. a basic run or two through the program.

Something that might help would be to include the line System.out.println("i:"+i+"; j:"+j+"; x:"+x+"; x:"+y); in the inner loop right after GRect square…. (as I’ve demonstrated in my code below) In Java, System.out.println will show things on the console. Putting in that line will make the program spit out a line each time it draws a square, giving the values of i, j, x, and y.

Finally, here’s an expanded version of the program with lots of comments. It also tells you about its progress, which hopefully will help you see what’s happening. Note that I wouldn’t normally use multiline comments (/*...*/) anywhere near this much.

import acm.graphics.GLabel;
import acm.graphics.GRect;
import acm.program.GraphicsProgram;

public class CheckerBoard extends GraphicsProgram {

  public void run() {
    double squareSize = (double) getHeight() / numRows;

    /*
     * Make a variable to carry the number of the square
     * that's being made. So, the first square will be
     * number 0, the second will be number 1, etc.
     */
    int num = 0;

    /*
     * Run the contents once for each number between 0 and
     * numRows Note the < and not <=. Because we're starting
     * from 0, we need to use <. For example, suppose we
     * wrote int i=0; i<=1; i++. We would get our loop run
     * once with i=0 and once with i=1 before i would not be
     * <= 1. Since our numbers in this case are supposed to
     * be the number of rows, we don't want to loop after we
     * do the one before our numRows or numColumns
     */
    for (int i = 0; i < numRows; i++) {
      /*
       * Run the contents of this loop once for each number
       * between 0 and numColumns, including 0, not
       * including numColumns.
       */
      for (int j = 0; j < numColumns; j++) {
        /*
         * Calculate the position for the next square. If
         * we're in column 4, then the next square should be
         * at 4*(the width of each square).
         */
        double x = j * squareSize;
        double y = i * squareSize;

        /*
         * Create a square that's to be put at our x and y
         * positions calculated just above. Make its width
         * squareSize and its height squareSize.
         */
        GRect square = new GRect(x, y, squareSize, squareSize);

        /*
         * Make some text that will be put down. Use the
         * current value of num for its text
         * (Integer.toString just makes that integer into
         * text), and put it at the x-position we're working
         * with plus 1/4 of a squareSize and the y-position
         * we're working with plus 3/4 of a square. This
         * fakes centering the text in the squares.
         */
        GLabel label = new GLabel(Integer.toString(num), x + squareSize * .25,
            y + squareSize * .75);

        /*
         * Tell the user what our i, j, x, y, and num values
         * are.
         */
        System.out.println("i:" + i + "; j:" + j + "; X:" + x + "; Y:" + y
            + "; num: " + num);

        square.setFilled((i + j) % 2 != 0);
        add(square);

        /*
         * Stick that label on the page, just like with the
         * square.
         */
        add(label);

        /*
         * Increment the number variable (add one to it) so
         * the next square is num+1 (if this is square 0,
         * then the next one should be square 1)
         */
        num++;
      }
    }
  }

  // Change this to make the checkerboard non-square.
  private static final int numRows = 8;
  private static final int numColumns = 8;
}

And here’s what I get on my console when I run it:

i:0; j:0; X:0.0; Y:0.0; num: 0
i:0; j:1; X:25.0; Y:0.0; num: 1
i:0; j:2; X:50.0; Y:0.0; num: 2
i:0; j:3; X:75.0; Y:0.0; num: 3
i:0; j:4; X:100.0; Y:0.0; num: 4
i:0; j:5; X:125.0; Y:0.0; num: 5
i:0; j:6; X:150.0; Y:0.0; num: 6
i:0; j:7; X:175.0; Y:0.0; num: 7
i:1; j:0; X:0.0; Y:25.0; num: 8
i:1; j:1; X:25.0; Y:25.0; num: 9
i:1; j:2; X:50.0; Y:25.0; num: 10
i:1; j:3; X:75.0; Y:25.0; num: 11
i:1; j:4; X:100.0; Y:25.0; num: 12
i:1; j:5; X:125.0; Y:25.0; num: 13
i:1; j:6; X:150.0; Y:25.0; num: 14
i:1; j:7; X:175.0; Y:25.0; num: 15
i:2; j:0; X:0.0; Y:50.0; num: 16
i:2; j:1; X:25.0; Y:50.0; num: 17
i:2; j:2; X:50.0; Y:50.0; num: 18
i:2; j:3; X:75.0; Y:50.0; num: 19
i:2; j:4; X:100.0; Y:50.0; num: 20
i:2; j:5; X:125.0; Y:50.0; num: 21
i:2; j:6; X:150.0; Y:50.0; num: 22
i:2; j:7; X:175.0; Y:50.0; num: 23
i:3; j:0; X:0.0; Y:75.0; num: 24
i:3; j:1; X:25.0; Y:75.0; num: 25
i:3; j:2; X:50.0; Y:75.0; num: 26
i:3; j:3; X:75.0; Y:75.0; num: 27
i:3; j:4; X:100.0; Y:75.0; num: 28
i:3; j:5; X:125.0; Y:75.0; num: 29
i:3; j:6; X:150.0; Y:75.0; num: 30
i:3; j:7; X:175.0; Y:75.0; num: 31
i:4; j:0; X:0.0; Y:100.0; num: 32
i:4; j:1; X:25.0; Y:100.0; num: 33
i:4; j:2; X:50.0; Y:100.0; num: 34
i:4; j:3; X:75.0; Y:100.0; num: 35
i:4; j:4; X:100.0; Y:100.0; num: 36
i:4; j:5; X:125.0; Y:100.0; num: 37
i:4; j:6; X:150.0; Y:100.0; num: 38
i:4; j:7; X:175.0; Y:100.0; num: 39
i:5; j:0; X:0.0; Y:125.0; num: 40
i:5; j:1; X:25.0; Y:125.0; num: 41
i:5; j:2; X:50.0; Y:125.0; num: 42
i:5; j:3; X:75.0; Y:125.0; num: 43
i:5; j:4; X:100.0; Y:125.0; num: 44
i:5; j:5; X:125.0; Y:125.0; num: 45
i:5; j:6; X:150.0; Y:125.0; num: 46
i:5; j:7; X:175.0; Y:125.0; num: 47
i:6; j:0; X:0.0; Y:150.0; num: 48
i:6; j:1; X:25.0; Y:150.0; num: 49
i:6; j:2; X:50.0; Y:150.0; num: 50
i:6; j:3; X:75.0; Y:150.0; num: 51
i:6; j:4; X:100.0; Y:150.0; num: 52
i:6; j:5; X:125.0; Y:150.0; num: 53
i:6; j:6; X:150.0; Y:150.0; num: 54
i:6; j:7; X:175.0; Y:150.0; num: 55
i:7; j:0; X:0.0; Y:175.0; num: 56
i:7; j:1; X:25.0; Y:175.0; num: 57
i:7; j:2; X:50.0; Y:175.0; num: 58
i:7; j:3; X:75.0; Y:175.0; num: 59
i:7; j:4; X:100.0; Y:175.0; num: 60
i:7; j:5; X:125.0; Y:175.0; num: 61
i:7; j:6; X:150.0; Y:175.0; num: 62
i:7; j:7; X:175.0; Y:175.0; num: 63

3

The double for-loop is essentially the same as this code:

int i = 0;

while (i <= numRows) {
    int j = 0;

    while (j <= numColumns) {
        double x = j * squareSize;
        double y = i * squareSize;
        GRect square = new GRect(x,y,squareSize,squareSize);
        square.setFilled((i + j) % 2 != 0);
        add(square);

        j++;
    }

    i++;
}

There is one small difference: at the end of the outer while-loop, i will have the value numRows + 1. If you use the for-loop the variable i will be out of scope.

Each time through the inner loop, a single board square is drawn (by adding it to the board). The following three lines of code draw the square:

GRect square = new GRect(x,y,squareSize,squareSize);
square.setFilled((i + j) % 2 != 0);
add(square);

(x,y) in the first line specify the upper left coordinate of the square to be drawn.

The second line determines the square color. As the inner and outer loops iterate, the value of i+j alternates between even and odd.

The squares are added in column order. After one full cycle of the inner loop, a new row of eight squares will be added.

The outer loop iterates once for each row, cycling through the inner loop to add the row.

A for loop is perhaps the most commonly used form of iteration. This loop performs initialization before the first iteration. Then it performs conditional testing and, at the end of each iteration, some form of “stepping.”

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật