三子棋是大家都很熟悉且玩起來比較輕鬆的小遊戲。那如何用C語言簡單去實現這個小遊戲呢?以下是我思路:
第一步:對於玩遊戲的人來說都有選擇玩或者不玩的權利,直接把遊戲放在玩家面前讓玩家去玩肯定是不合理的,所以我們得先打印出一個簡單的遊戲菜單供玩家選擇,這裏我們自定義一個函數menu()幫我們實現打印菜單。然後在用switch語句去判斷玩家的選擇。爲了使玩家結束一局三子棋遊戲後還可以選擇是否繼續三子棋遊戲,這裏可以使用do...while()循環。
第二步:自定義遊戲函數game(),首先定義一個二維數組board[ ][ ]目的是爲了玩家輸入座標以實現落子。在定義數組後再調用自定義函數init_board()將數組內元素初試化爲' '。接下來得實現打印棋盤、玩家和電腦落子、根據已經落子的情況判斷輸贏。
1.定義函數display_board()來實現打印棋盤,用字符'-'和字符'|'我們可以打印出我們想要的棋盤。打印棋盤過程中先將棋盤中的每一行看成一個整體使用一個for循環打印,然後再將每行中的每一格用for循環將其依次打印。
2.定義函數PlayerMove()來實現玩家落子,玩家輸入的棋子座標的兩個值必將都大於0但是有可能會超出棋盤範圍,所以得判斷玩家輸入棋子座標的合理性,如果超出棋盤範圍就報錯使其重新輸入直到正確爲止,其次在判斷玩家輸入的座標位置是否已經有棋,如果有棋的話報錯讓玩家重新輸入。這裏將玩家下的棋子用來打印在棋盤上。再定義函數ComputerMove()來實現電腦落子,電腦落子相比玩家落子簡單,只要隨機生成座標落子,然後生成座標處是否有棋。沒有直接落子,有的話繼續隨機生成座標直到座標處無棋。
3.既然是三子棋,那表示橫線、豎線、兩種對角線上有連續三個相同的棋子就表示該棋子方獲勝,或者棋盤落滿都沒有連續的三個棋子時則判平局。
代碼如下:
//頭文件
game.h
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 3
#define COL 3
void maue();
void game();
void init_board(char board[ROW][COL], int row, int col);
void display_board(char board[ROW][COL], int row, int col);
void PlayerMove(char board[ROW][COL], int row, int col);
void ComputerMoveint(char board[ROW][COL], int row, int col);
char CheckWin(char board[ROW][COL], int row, int col);
game.c
#include "game.h"
void init_board(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] = ' ';
}
}
}
void display_board(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++)
{
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] != ' ')
{
printf("該位置有棋子,請重新落子\n");
}
else
{
board[x - 1][y - 1] = '*';
break;
}
}
else
{
printf("輸入有誤,請重新輸入\n");
}
}
}
void ComputerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("電腦走:>\n");
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
static int IsFull(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++)
{
if(board[i][j] == ' ')
return 0;
}
}
return 1;
}
char CheckWin(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 - 2; j++)
{
if ((board[i][j] == board[i][j + 1]) && (board[i][j + 1] == board[i][j + 2]) && (board[i][j] != ' '))
return board[i][j];
}
}
for (j = 0; j < col; j++)
{
for (i = 0; i < row - 2; i++)
{
if ((board[i][j] == board[i + 1][j]) && (board[i + 1][j] == board[i + 2][j]) && (board[i][j] != ' '))
return board[i][j];
}
}
for (i = 0; i < row - 2; i++)
{
for (j = 0; j < col - 2; j++)
{
if ((board[i][j] == board[i + 1][j + 1]) && (board[i + 1][j + 1] == board[i + 2][j + 2]) && (board[i][j] != ' '))
return board[i][j];
}
}
for (i = 0; i < row - 2 ; i++)
{
for (j = 2; j < col; j++)
{
if ((board[i][j] == board[i + 1][j - 1]) && (board[i + 1][j - 1] == board[i + 2][j - 2]) && (board[i][j] != ' '))
return board[i][j];
}
}
if (IsFull(board, row, col) == 1)
{
return 'Q';//平局
}
return 'C';//繼續
}
//實現三子棋的主函數
#include "game.h"
void maue()
{
printf("**************************\n");
printf("****** 1.play ******\n");
printf("****** 0.exit ******\n");
printf("**************************\n");
}
void game()
{
char board[ROW][COL] = { 0 };
char ret = 0;
init_board(board, ROW, COL);
display_board(board, ROW, COL);
while (1)
{
PlayerMove(board, ROW, COL);
display_board(board, ROW, COL);
ret = CheckWin(board, ROW, COL);
if (ret != 'C')
break;
ComputerMove(board, ROW, COL);
display_board(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");
}
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
maue();
printf("請輸入到你的選擇:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出遊戲!\n");
break;
default:
printf("輸入錯誤,請重新輸入:>\n");
break;
}
} while (input);
system("pause");
return 0;
}
注:
1.在定義二維數組board[ ][ ]時可以直接在填入具體的數值表示棋盤的大小,後期如果想改變棋盤大小時就必須得將整個代碼中的board[ ][ ]的數值修改。由於過於繁瑣所以在頭文件中用#define來修飾ROW,COL來表示棋盤大小的值。後期只要改變頭文件中這兩個值就可以改變棋盤大小。
2.玩家落子和電腦落子後緊跟着打印棋盤,以保證落子後都能看到棋盤上落子的具體情況。每次落子後還得對棋盤的格局進行判斷,如果沒有任何一方獲勝或者平局則繼續落子,否則跳出循環判斷哪方獲勝或者平局。
代碼中有有的表述可能過於繁瑣,如有不當之處請指出,以便修改。