試題 演算法訓練 K好數
淺談C語言中的三子棋小遊戲
1. 三子棋的思考過程:
很多小白在一開始看到這個三子棋,會感覺到無從下手,不知道應該把哪裡作為突破口,但是大可不必,只需要在腦子中將這個遊戲的幾個步驟分成一個個小程式,把它們一個個寫出來,然後將它們像組裝零件一樣組裝起來,即可。
步驟如下:
(1)起始介面
(2)初始化棋盤
(3)列印棋盤
(4)玩家輸入
(5)位置是否合法判斷
(6)輸贏判斷
(7)電腦輸入
(8)輸贏判斷
(9)結束
是不是拆分成一個個部分就想得出來了?
那接下來就是零件的製造了
2. 零件製造
這次我們分別建立game.h,game.c和test.c,
game.h檔案中主要寫一些預處理資訊、一些需要用到的現有的函式的標頭檔案和自定義函式的宣告。
test.c檔案中就主要寫三子棋遊戲的主體程式碼。
起始介面
起始介面寫於test.c中
void menu()
{
printf("************************\n");
printf("*********1.play*********\n");
printf("*********0.exit*********\n");
printf("************************\n");
}
初始化棋盤
在game.h檔案中先對初始化棋盤的函式進行宣告,再在game.c中對其進行具體定義
void InitBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
其中的ROW和COL,是我們在game.h檔案中巨集定義的兩個數,這樣的話,就避免因為條件的變換,而大幅度更改程式碼。
列印棋盤
void DisplayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)
printf("|");
}
printf("\n");
//列印分割的行
if (i < row - 1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
printf("\n");
}
}
}
玩家輸入並位置是否合法判斷
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家走:>\n");
while (1)
{
printf("請輸入一個座標:>");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '#';
break;
}
else
printf("座標被佔用,請重新輸入!\n");
}
else
{
printf("座標非法,請重新輸入!\n");
}
}
}
電腦輸入
void ComputerMove(char board[ROW][COL], int row, int col)
{
printf("電腦走:>\n");
while (1)
{
int x = rand() % row;
int y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '*';
break;
}
}
}
因為電腦在這是隨意下棋的,所以我們在這引入一個隨機變數
rand();生成隨機數,它的標頭檔案是<stdlib.h>,因為在使用rand函式之前要呼叫srand(x)函式,並且要求x要時刻變化,所以我們要引用時間戳。
srand((unsigned int)time(NULL));
其中NULL為空指標,為了讓每一次程式的呼叫都產生不同的值,所以經常使用系統時間來初始化,也就是time(NULL)。time的標頭檔案為<time.h>,所以我們還需在game.h中將其寫入開頭。
輸贏判斷
game.c中
char CheckWin(char board[ROW][COL], int row, int col)
{
int i = 0;
//判斷行
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
return board[i][0];
}
//判斷列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
return board[0][i];
}
//判斷對角線
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
return board[0][0];
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')
return board[0][2];
//判斷是否為和其
if (IsFull(board, row, col) == 1)
return 'q';
//勝負未定,繼續遊戲
return 'c';
}
test.c中
if (ret == '#')
printf("玩家贏\n");
else if (ret == '*')
printf("電腦贏\n");
else if (ret == 'q')
printf("和棋\n");
零件都做好了,接下是組裝了
3. 組裝
在組裝的時候,如果還要考慮到視窗整潔明瞭,可以用system(“cls”);來對視窗進行清理。
其中game()是其它函式的整和,在其中進行。
void game()
{
char ret = 0;
char board[ROW][COL];
//初始化
InitBoard(board, ROW, COL);
//列印棋盤
DisplayBoard(board, ROW, COL);
while (1)
{
//玩家下棋
PlayerMove(board, ROW, COL);
system("cls");
DisplayBoard(board, ROW, COL);
ret = CheckWin(board, ROW, COL);
if (ret != 'c')
break;
//電腦下棋
ComputerMove(board, ROW, COL);
system("cls");
DisplayBoard(board, ROW, COL);
ret = CheckWin(board, ROW, COL);
if (ret != 'c')
break;
}
if (ret == '#')
printf("玩家贏\n");
else if (ret == '*')
printf("電腦贏\n");
else if (ret == 'q')
printf("和棋\n");
}
總結
這是我身為小白寫的第一篇關於C語言內容的部落格,我在聽老師講解的時候也是一知半解,寫程式碼的時候也是寫一點,改一點;但是當我寫完這篇部落格後,我感覺我對這個小遊戲的瞭解更加深了,知識也鞏固了。希望我的這篇部落格可以對你起到一些幫助;也希望可以指出我的問題或者給我多補充點知識,我會很開心。