基于C語言實(shí)現(xiàn)井字棋游戲
井字棋游戲要求在3乘3棋盤上,每行都相同或者每列都相同再或者對(duì)角線相同,則勝出.因此我們可以使用一個(gè)二維數(shù)組來表示棋盤,判斷勝負(fù)只需要判斷數(shù)組元素是否相同即可.具體我們可以分為以下幾步來做:
1.創(chuàng)建維數(shù)組并進(jìn)行初始化,如果僅僅是一個(gè)二維數(shù)組來表示棋盤,看起來不是很清楚,因此我們可以對(duì)棋盤邊框用符號(hào)打印出來進(jìn)行優(yōu)化一下:
//初始化棋盤 void init(char board[max_row][max_col]) { for (int row = 0; row < max_row; row++) { for (int col = 0; col < max_col; col++) { board[row][col] =' '; } } srand((unsigned int)time(0)); } //打印棋盤 void print(char board[max_row][max_col]) { system("cls");//每次打印之前清除掉上一次的結(jié)果. for (int a = 0; a < max_col; a++) { printf("+---+---+---+\n"); for (int b = 0; b < max_row; b++) { printf("| %c ", board[a][b]); } printf("| \n"); } printf("+---+---+---+\n"); }
2.進(jìn)行玩家落子,同樣是使用數(shù)組操作,讓玩家輸入相對(duì)應(yīng)的坐標(biāo),在二維數(shù)組的該位置打印'x'來表示玩家下的棋子
void play(char board[max_row][max_col]) { printf("玩家落子階段!\n"); int a; int b; while (1) { printf("請(qǐng)輸入想要落子的坐標(biāo): "); scanf("%d %d", &a, &b); //判定玩家落子坐標(biāo)是否在有效范圍內(nèi) if (a < 0 || b < 0 || a >= max_row || b >= max_col) { printf("輸入坐標(biāo)有誤請(qǐng)重新輸入!\n"); continue; } //判定落子處是否已經(jīng)存在了棋子 if (board[b][a] != ' ') { printf("此處已被落子無法再落子,請(qǐng)重新輸入!\n"); continue; } board[b][a] = 'x'; //用'x'表示玩家落子 break; } }
3.玩家落子結(jié)束后讓電腦在二維數(shù)組中隨機(jī)落子,使用rand函數(shù)產(chǎn)生0到2的隨機(jī)數(shù)進(jìn)行賦值操作,進(jìn)而實(shí)現(xiàn)電腦隨機(jī)落子
void computer(char board[max_row][max_col]) { printf("電腦落子階段!\n"); while (1) { int a = rand() % max_row; //產(chǎn)生0到2的隨機(jī)數(shù) int b = rand() % max_col; if (board[a][b] != ' ') { //判斷所下位置是否已經(jīng)有子 continue; } board[a][b] = 'o'; break; }
4.判斷勝負(fù),當(dāng)玩家落子結(jié)束,或者電腦落子結(jié)束后,判斷是否存在某行或某列或者對(duì)角線有相同的元素,如果有則直接判定結(jié)果,如果沒有則輪到下家落子
char check(char board[max_row][max_col]) { //檢測所有行是否相等 for (int cow = 0; cow < max_row; cow++) { if (board[cow][0] != ' ' && board[cow][0] == board[cow][1] && board[cow][0]==board[cow][2] ) { return board[cow][0]; } } //檢測所有列是否相等 for (int col = 0; col < max_col; col++) { if (board[0][col] != ' ' && board[0][col] == board[1][col] && board[0][col]==board[2][col] ) { return board[0][col]; } } //檢測對(duì)角線是否相等 if (board[0][0] != ' ' && board[0][0] == board[1][1] && board[0][0] == board[2][2]) { return board[0][0]; } if (board[0][2] != ' ' && board[0][2] == board[1][1] && board[0][2] == board[2][0]) { return board[0][2]; } if (pingju(board)) { return 'q'; //棋子已滿和棋 } return 'a'; //棋盤未滿 } //判斷棋盤是否棋子已滿,如果滿了返回1,未滿返回0. int pingju(char board[max_row][max_col]) { for (int row = 0; row < max_row; row++) { for (int col = 0; col < max_col; col++) { if (board[row][col] == ' ') { return 0; } } } return 1; }
5.在主函數(shù)中調(diào)用以上函數(shù),進(jìn)行操作:
int main() { char board[max_row][max_col] = {0};//數(shù)組初始化為0 char winner = 'n'; init(board); //將棋盤中元素初始化為空格 while (1) { print(board); //打印棋盤 play(board); //玩家落子 winner = check(board); //判斷勝負(fù) if (winner != 'a') { break; } computer(board); //電腦落子 winner = check(board); //判斷勝負(fù) if (winner != 'a') { break; } } if (winner == 'x') { print(board); printf("你贏了!"); } else if (winner == 'o') { print(board); printf("你輸了!"); } else if (winner == 'q') { print(board); printf("和棋!"); } return 0;
在主函數(shù)中利用while循環(huán)來實(shí)現(xiàn)玩家與電腦的輪流落子,如果當(dāng)一方落子之后勝負(fù)已出,則跳出循環(huán)直接打印最終結(jié)果.
完整代碼如下:
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <windows.h> #define max_row 3 #define max_col 3 //初始化棋盤 void init(char board[max_row][max_col]) { for (int row = 0; row < max_row; row++) { for (int col = 0; col < max_col; col++) { board[row][col] =' '; } } srand((unsigned int)time(0)); } //打印棋盤 void print(char board[max_row][max_col]) { system("cls");//每次打印之前清除掉上一次的結(jié)果. for (int a = 0; a < max_col; a++) { printf("+---+---+---+\n"); for (int b = 0; b < max_row; b++) { printf("| %c ", board[a][b]); } printf("| \n"); } printf("+---+---+---+\n"); } //玩家落子 void play(char board[max_row][max_col]) { printf("玩家落子階段!\n"); int a; int b; while (1) { printf("請(qǐng)輸入想要落子的坐標(biāo): "); scanf("%d %d", &a, &b); //判定玩家落子坐標(biāo)是否在有效范圍內(nèi) if (a < 0 || b < 0 || a >= max_row || b >= max_col) { printf("輸入坐標(biāo)有誤請(qǐng)重新輸入!\n"); continue; } //判定落子處是否已經(jīng)存在了棋子 if (board[a][b] != ' ') { printf("此處已被落子無法再落子,請(qǐng)重新輸入!\n"); continue; } board[a][b] = 'x'; //用'x'表示玩家落子 break; } } // void computer(char board[max_row][max_col]) { printf("電腦落子階段!\n"); while (1) { int a = rand() % max_row; //產(chǎn)生0到2的隨機(jī)數(shù) int b = rand() % max_col; if (board[a][b] != ' ') { //判斷所下位置是否已經(jīng)有子 continue; } board[a][b] = 'o'; break; } // } // char check(char board[max_row][max_col]) { //檢測所有行是否相等 for (int cow = 0; cow < max_row; cow++) { if (board[cow][0] != ' ' && board[cow][0] == board[cow][1] && board[cow][0]==board[cow][2] ) { return board[cow][0]; } } //檢測所有列是否相等 for (int col = 0; col < max_col; col++) { if (board[0][col] != ' ' && board[0][col] == board[1][col] && board[0][col]==board[2][col] ) { return board[0][col]; } } //檢測對(duì)角線是否相等 if (board[0][0] != ' ' && board[0][0] == board[1][1] && board[0][0] == board[2][2]) { return board[0][0]; } if (board[0][2] != ' ' && board[0][2] == board[1][1] && board[0][2] == board[2][0]) { return board[0][2]; } if (pingju(board)) { return 'q'; } return 'a'; } //判斷棋盤是否棋子已滿,如果滿了返回1,未滿返回0. int pingju(char board[max_row][max_col]) { for (int row = 0; row < max_row; row++) { for (int col = 0; col < max_col; col++) { if (board[row][col] == ' ') { return 0; } } } return 1; } int main() { char board[max_row][max_col] = {0};//數(shù)組初始化為0 char winner = 'n'; init(board); //將棋盤中元素初始化為空格 while (1) { print(board); //打印棋盤 play(board); //玩家落子 winner = check(board); //判斷勝負(fù) if (winner != 'a') { break; } computer(board); //電腦落子 winner = check(board); //判斷勝負(fù) if (winner != 'a') { break; } } if (winner == 'x') { print(board); printf("你贏了!"); } else if (winner == 'o') { print(board); printf("你輸了!"); } else if (winner == 'q') { print(board); printf("和棋!"); } return 0; }
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
delete[] p->elems和free(p->elems)區(qū)別介紹
delete[]和free()都是釋放內(nèi)存的函數(shù),但它們具有不同的使用方法和適用情況,這篇文章主要介紹了delete[] p->elems和free(p->elems)有什么區(qū)別,需要的朋友可以參考下2023-04-04C++11關(guān)于auto關(guān)鍵字的使用示例
今天小編就為大家分享一篇關(guān)于C++11關(guān)于auto關(guān)鍵字的使用示例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12詳解C++編程中的重載流插入運(yùn)算符和流提取運(yùn)算符
這篇文章主要介紹了詳解C++編程中的重載流插入運(yùn)算符和流提取運(yùn)算符,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-09-09C/C++ 中堆和棧及靜態(tài)數(shù)據(jù)區(qū)詳解
這篇文章主要介紹了C/C++ 中堆和棧及靜態(tài)數(shù)據(jù)區(qū)詳解的相關(guān)資料,需要的朋友可以參考下2017-04-04