使用C語言實現一個三子棋小游戲
涉及知識點:二維數組
、自定義函數
、自帶函數庫
、循環
、常量
、動態取地址
等等
一些細節點:
1、引入自定義頭文件,需要用""
雙引號包裹文件名,目的是為了和官方頭文件的<>
區分開。
如#include "game.h"
2、使用rand()
函數,需要先調用sand()
,保證每次隨機函數生成的值均不一樣
3、為了使srand()
擁有隨機種子,可以使用時間戳函數time()
作為值傳入使用
4、自定義方法首字母大寫,是為了和官方函數庫區分開
三子棋代碼如下:
效果
代碼
函數頭文件 game.h
#include <stdio.h>
#include <time.h>// 定義棋盤的行與列(二位數組的大小)
#define ROW 3
#define COL 3// 菜單打印
void Menu();
//開始游戲
void Game();// 初始化棋盤
void InitChessboard(char board[ROW][COL], int row, int col);
// 打印棋盤
void PrintBoard(char board[ROW][COL], int row, int col);
// 玩家輸入
void PlayerInput(char board[ROW][COL], int row, int col);
//電腦輸入
void ComputerInput(char board[ROW][COL], int row, int col);
// 判斷棋局是否結束
char IsEnd(char board[ROW][COL], int row, int col);
函數主文件 game.c
#define _CRT_SECURE_NO_WARNINGS
// 引入自定義函數頭文件
#include "game.h"// 菜單選項
void Menu()
{printf("***************三子棋***************\n");printf("******* 1.開始游戲 0.退出游戲 ******\n");printf("************************************\n");}// 打印棋盤
void PrintBoard(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){int k = 0;for (k = 0; k < col; k++){printf("---");if (k < col - 1){printf("|");}}printf("\n");}}printf("\n");
}// 初始化棋盤
void InitChessboard(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 PlayerInput(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;while (1){printf("玩家請下棋(格式為數字+空格+數字,按下回車確認)\n請輸入坐標:");scanf("%d %d", &x, &y);// 判斷玩家輸入值是否超出棋盤if ((x > ROW || x < 1) || (y > COL || y < 1) ){printf("坐標值超出棋盤大小,請重新輸入\n");}// 判斷坐標位置是否已有棋子else if(board[x-1][y-1] != ' '){printf("該位置已存在棋子,請重新輸入\n");}// 滿足條件,可下棋else{board[x-1][y-1] = '*';// 約定:玩家下棋用*表示break;}}}// 電腦下棋
void ComputerInput(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;while (1){// 產生一個隨機位置 范圍[0, ROW/COL - 1]x = rand() % ROW; // 行位置y = rand() % COL; // 列位置// 因為隨機數的產生做了限制,此處無須再做數值的有效性校驗// 位置是否沖突校驗(等于空格則認為該位置可下)if (board[x][y] == ' '){board[x][y] = '#';// 約定:電腦下棋用#表示break;}}printf("電腦下棋\n");
}// 判斷棋局是否結束
char IsEnd(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][2] != ' '){return board[0][0];}}// 列int j = 0;for ( j = 0; j < COL; j++){// 有一列相同就認為完成三連if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[2][j] != ' '){return board[0][0];}}// 斜角if ((board[0][0] == board[1][1]) && (board[1][1] == board[2][2]) && board[2][2] != ' '){return board[0][0];}if ((board[0][2] == board[1][1]) && (board[1][1] == board[2][0]) && board[2][0] != ' '){return board[0][2];}// 判斷平局int x = 0;int y = 0;for (x = 0; x < ROW; x++){for (y = 0; y < COL; y++){// 但凡存在一個空格說明棋盤還有空位if (board[x][y] == ' '){return 'g'; // go on 繼續}}}return 'd';// dogfall 表示平局
}void Game()
{char board[ROW][COL] = { 0 };//初始化棋盤InitChessboard(board, ROW, COL);//打印棋盤PrintBoard(board, ROW, COL);char res = 0;// 循環表示玩家和電腦依次下棋while (1){// 玩家輸入PlayerInput(board, ROW, COL);// 輸入完畢打印棋盤PrintBoard(board, ROW, COL);// 判斷棋局是否結束res = IsEnd(board, ROW, COL);// 不為g表示有了結果,為g就繼續下棋if ('g' != res){break;}//電腦輸入ComputerInput(board, ROW, COL);// 輸入完畢打印棋盤PrintBoard(board, ROW, COL);// 判斷棋局是否結束res = IsEnd(board, ROW, COL);// 不為g表示有了結果,為g就繼續下棋if ('g' != res){break;}}// 判斷贏家/平局if ('*' == res){printf("玩家獲勝!\n");}else if ('#' == res){printf("電腦獲勝!\n");}else{printf("平局!\n");}}
main函數入口文件 test.c
#define _CRT_SECURE_NO_WARNINGS#include "game.h"int main()
{// 三子棋int a = 0;do{// srand 保證隨機數每次生成均不一樣srand((unsigned int)time(NULL));//打印菜單Menu();printf("請輸入:");scanf("%d", &a);if (1 == a){printf("------三子棋游戲開始------\n\n");// 開始游戲Game();}else if(0 == a){printf("退出游戲\n");return;} else{printf("輸出數字錯誤,請重新輸入\n");}} while (a);return 0;
}