Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

C programming Prints out all of the required information for all assignments (se

ID: 674382 • Letter: C

Question

C programming

Prints out all of the required information for all assignments (see style sheet)

Your program should have at least 4 functions (including main)

Your program should allow two people to play tic-tac-toe Using a 500 wide by 600 tall graphics window and their mouse.

One function should print out the board (the playing area which is the top 500x500 pixels). This function should be of type void, take a single argument which should be two dimensional array with dimensions 3x3. (hint, have each element in the array represent the status of that square (e.g., 0 means unclaimed, 1 means there is an X and 2 means there is an O in the square).

Another function should be the win check function which returns 0 if no one has won the game, and some other value if someone has won. This function should take the 2D array representing the board, and other parameters which might be useful (Hint: The position of the last square filled might be useful information to decide if someone has just won.)

A third function should be the mouseMove function which takes the 2D array representing the board and a parameter that represents which player is making the move (player 1 who is X or player 2 who is O). This function should read the mouse, print a message on the status line if the user tries to click in an illegal spot (eg, outside of the board or in a space that is already claimed) and return when a legal spot has been selected by the mouse being clicked and released and in a legal position. The function should modify the board with the new move. Hint: This function needs to let main know what move has been chosen: One can pass the row and column chosen back by having a position array that is modified in the function, two integer variables that are passed by reference so they can be modified in the function, or return a single integer that represents the position selected (eg a number 1 to 9).

Your main function should open the 500x600 graphics window, initialize the board, and then loop up to nine times, stopping when the board has been filled or the game has been won. The program should then print out in the status area who has won, or if the game has been a tie. If a winner has been declared your program should put a line across the three winning marks.

Explanation / Answer

The Tic Tac Toe Board In order to draw the board, the computer has to remember each player's moves. One way to remember all the moves is to store the whole board using names like this.
square[1] square[2] square[3] square[4] square[5] square[6] square[7] square[8] square[9]
Choosing a name to remember the contents of the 9 squares is only the beginning. Each of those squares can have three possible states:
• no one has chosen that square yet, it is blank
• the square holds an X
• the square holds an O
The program could use numbers 1, 2, and 3 in each state to mean empty, x, and o, but it is more readable to use “ “, “x”, and “o” to remember these three possibilities. Before the game starts, start the board as empty: square := list(9, “ “) This is the same as saying square := [“ “, “ “, “ “, “ “, “ “, “ “, “ “, “ “, “ “] in both cases the name square holds a list of 9 things which are spaces. Consider the following textual way to display the tic-tac-toe board. The character "-" is used to draw horizontal lines, while "|" draws vertical lines. The next version of this program will draw the boxes using a graphical picture. write(“-------”) every i := 1 to 3 do write(“|”,square[i*3-2],”|”, square[i*3-1],”|”, square[i*3],”|”) write(“-------”) Taking Turns Tic Tac Toe switches back and forth between x and o, so the computer needs to remember which player played last. Player x starts. To remember something like whose turn it is, make up a name and use := to store a value using that name. turn := "x" Now comes some tricky business. The computer must play a lot of turns (up to 9 of them), and each turn does pretty much the same thing: show the board, wait for the player to make his move, and then draw an x or an o. The following code outline shows how to repeat something 9 times, changing the “turn” each time. The lines that start with a # are telling you what instructions the program needs, but they aren't instructions, they are just comments to any human who happens to read the program. Drawing the board was already presented above. The sections to follow will need to add instructions that read the players' moves and check if they won.
every 1 to 9 do {
# draw the board
# read the player's move (x or o)
# check if game is over
if turn == “x” then turn := “o” else turn := “x”
}
The game is over when there are three in a row of the same letter, x or o, or if no squares remain blank. You can check for a win using calls to a helper procedure: if won := check_win(board) then stop(“Player “, won, “wins”) The check_win() procedure is given below. It returns an x or an o if the corresponding player has won. The tests of equality produce their right operand if they succeed; if they do not, the return does not occur. The procedure fails if it falls off the end. procedure check_win(board)
every i := 1 to 3 do {
# check horizontally return board[i*3-2]==board[i*3-1]==board[i*3]==(“x”|”o”)
# check vertically return board[i]==board[i+3]==board[i+6]==(“x”|”o”)
}
# check diagonals return board[1]==board[5]==board[9]==(“x”|”o”)
return board[3]==board[5]==board[7]==(“x”|”o”) end
Reading the Player's Move Reading the human user's input sounds simple (just read an x or an o) but it is a bit trickier than that. The program already knows whether the player is drawing an x or an o, it needs to find out what location to draw it in. Locations are identified by a 1-9, but the program has to check and make sure the user does not mark a position that is already played, or type nonsense into the program! It also needs to provide an explanatory prompt to tell the user what it is expecting.
repeat {
write(“It is player “, turn,“'s turn. Pick a square from 1 to 9:”) pick := read()
if square[integer(pick)] == “ “ then break
}
square[pick] := turn
A Complete Two-Player Tic Tac Toe Program The complete program is
procedure main()
turn := "x"
square := list(9, “ “)
every 1 to 9 do
{
# draw the board
write(“-------”)
every i := 3 to 9 by 3
do {
write(“|”,square[i-2],”|”, square[i-1],”|”, square[i],”| -------”)
}
# read the player's move (X or O)
repeat {
write(“It is player “, turn “'s turn. Pick a square from 1 to 9:”)
pick := read()
if square[integer(pick)] == “ “ then break
}
square[pick] := turn
if won := check_win(board) then stop(“Player “, won, “wins”)
# advance to the next turn
if turn == “x” then turn := “o” else turn := “x”
}
write(“Cat game!”) end
# Check if the game is over; return the winner if there is one procedure
check_win(board)
very i := 1 to 3 do {
# check horizontally
return board[i*3-2]==board[i*3-1]==board[i*3]==(“x”|”o”)
# check vertically
return board[i]==board[i+3]==board[i+6]==(“x”|”o”)
}
# check diagonals
return board[1]==board[5]==board[9]==(“x”|”o”)
return board[3]==board[5]==board[7]==(“x”|”o”)
end

Drawing lines and circles in a window is done using using graphics. To draw some graphics you have to first tell the computer to put a window on the screen. procedure main() &window := open("TicTacToe", "g", "size=600,600", "linewidth=5") The call to open() takes several parameters: first a name, then a mode ("g" stands for graphics), then how big you want the window to be, and lastly how wide the lines should be drawn. In this case we want a window 600 dots wide and 600 dots high. Each dot is called a pixel, and to pick out a particular pixel you give its location as: how far over from the left edge (the "x" coordinate) and how far down from the top (the "y" coordinate). To draw the Tic Tac Toe board, we want to draw lines from top to bottom at locations 200 and 400, which are one third and two thirds of the way across. DrawLine(200,0,200,600) DrawLine(400,0,400,600) DrawLine(0,200,600,200) DrawLine(0,400,600,400) There is a function named Event() that waits until the person running your program types a key or clicks the mouse. There are many different events, but the only one we care about is a left mouse click, called &lpress. So we read one event, but if it isn't a left mouse click, the next instruction will take us back to the repeat so we can ask for another event. "if" and "then" are used to do an instruction only after checking and seeing whether something is true: if Event() ~=== &lpress then next We divide the Tic Tac Toe board into three rows, from top to bottom, numbered 0, 1, and 2. Similarly we divide the boardi into three columns, from left to right, numbered 0, 1, and 2. On a mouse click, the location where the mouse is can be found in &x and &y. These numbers are how many dots from the top left corner of the window. To find the row and column in the Tic Tac Toe board, we divide by 200, and remember the results using a name we can ask for later: y := &y / 200 x := &x / 200 Now, draw a red x or a green o, depending on whose turn it is. The name turn is remembering whose turn it is, and after we draw an x or an o we change to the other player's turn. The Fg() instruction tells what foreground color to draw with, and to draw an x we just draw two lines.
if turn == "x" then { # draw an X
Fg("red")
DrawLine(x*200 + 20, y*200 + 20,
x*200 + 160, y*200 + 160)
DrawLine(x*200 + 20, y*200 + 160,
x*200 + 160, y*200 + 20)
turn := "o"
}
If you want, the if-then instruction lets you put in an "else" instruction which tells what to do if the condition you checked wasn't true. If it isn't x's turn it is o's turn, so we should draw a circle.
else {
# draw on O
Fg("green")
DrawCircle(x * 200 + 100, y * 200 + 100, 60)
turn := "x"
}
} end
This is a pretty interesting program with a lot of ideas in it, but it is only 28 lines of code, and if you ask enough questions you should be able to understand every line. Later on after you learn more, you might come back to this program and teach it how to stop anyone from making an illegal move, how to quit, and how to tell who wins. Here is the complete program so you can type it in and try it:
procedure main()
&window := open("TicTacToe","g", "size=600,600", "linewidth=5")
DrawLine(200,0,200,600)
DrawLine(400,0,400,600)
DrawLine(0,200,600,200)
DrawLine(0,400,600,400)
turn := "x" repeat {
if Event() ~=== &lpress then next
y := &y / 200
x := &x / 200
if turn == "x" then {
# draw an X
Fg("red")
DrawLine(x * 200+20, y * 200+20,
x * 200 + 160, y * 200 + 160)
DrawLine(x * 200+20, y * 200 + 160,
x * 200 + 160, y * 200 + 20)
turn := "o"
}
else {
# draw on O
Fg("green")
DrawCircle(x * 200 + 100, y * 200 + 100, 60)
turn := "x"
}
} end
Adding a Computer Player The first step towards providing an “intelligent” computer player for a turn-based game like Tic Tac Toe is to encapsulate the task of
choosing the move for a given side. First, add a command-line argument to specify whether the human is playing “x” or “o”, at the front of the main()
procedure:
human := (argv[1] == (“x”|”o”)) | “x”
The code for choosing the current move then becomes:
if human==turn then {
# read the player's move (X or O)
pick := humanmove(square, turn)
} else
{ pick := computermove(square, turn)
}
The humanmove() code is just a straightforward packaging of the repeat loop given earlier, but the computermove() code is strangely similar. Given the current program state, it asks that a move be selected. In the following example, the move is selected by trying moves at random until a legal move is found:
procedure computermove(square, turn)
write("...")
repeat { pick := ?9
if square[integer(pick)] == " " then break
}
delay(500)
return pick end The write(“...”) and the half-second delay are inserted just to give the human time to notice that the computer has made its move.

Making the Computer Smarter If you are playing solitaire, this “dumb” computer player may be more entertaining than moving the pieces for both sides yourself. A more satisfying computer player will at least rate its available moves in order to select which one it will choose. procedure computermove(square, turn)
every square[i := 1 to 9] == " " do {
newboard := copy(square)
newboard[i] := turn
pick := evaluate(newboard, turn)
if /bestpick | (pick > bestpick) then bestpick := pick
}
return bestpick end The real question, then, is how to evaluate board positions from the point of view of a given player. How to you evaluate a given board position in a strategy game? Usually, there is an absolute best and worst (where the game is won or lost outright), and otherwise it comes down to an opinion based on how the pieces are lined up. The technical term for this is heuristic – an evaluation that is just based on (hopefully good) judgment, without a guarantee of correctness or optimality, is a heuristic judgment. When a judgment is formed by a combination of such rules of thumb, we say the evaluation is based on heuristics. Here is a sample set of heuristics: • if I have a win: award the board position +10000 • if the opponent has a win: award the board position -10000 • for every opponent's unblocked two-in-a-row, award -1000 • for every one of my unblocked two-in-a-row, award +300 Combining these rules, we get the following evaluator:
procedure evaluate(board, turn)
if won := check_win(board) then
return if won == turn then 10000 else -10000
points := 0
every play := two_in_row(board, turn) do
if play==turn then points +:= 300
else points -:= 1000
return points end In order to finish this version, another helper function is required. We will contemplate how all these helper functions that evaluate board positions would be easier to keep straight if we had a new data type for evaluating and operating on board positions. The way such data types are introduced is called object-oriented programming. # generate all the un-blocked two-in-a-rows procedure two_in_row(board, turn)
every i := 1 to 3 do {
# check horizontally
if board[i*3-2]==” “ & board[i*3-1]==board[i*3] then
suspend board[i*3]
if board[i*3-1]==” “ & board[i*3-2]==board[i*3] then
suspend board[i*3]
if board[i*3]==” “ & board[i*3-2]==board[i*3-1] then
suspend board[i*3-1]
# check vertically
if board[i] == “ “ & board[i+3]==board[i+6] then
suspend board[i+6]
if board[i+3] == “ “ & board[i]==board[i+6] then
suspend board[i]
if board[i+6] == “ “ & board[i]==board[i+3] then
suspend board[i]
}
# check diagonals
if board[1]==” “ & board[5]==board[9] then suspend board[5]
if board[5]==” “ & board[1]==board[9] then suspend board[1]
if board[9]==” “ & board[1]==board[5] then suspend board[1]
if board[3]== “ “ & board[5]==board[7] then suspend board[5]
if board[5]== “ “ & board[3]==board[7] then suspend board[3]
if board[7]== “ “ & board[3]==board[5] then suspend board[3]
end