C語(yǔ)言實(shí)現(xiàn)三子棋游戲含完整代碼
?三子棋是大家小時(shí)候和同桌在紙上都玩過(guò)的簡(jiǎn)單小游戲,這個(gè)游戲我們?cè)赾語(yǔ)言中就可以實(shí)現(xiàn)。
在這篇文章我推薦大家使用vs2013,vs2019,vs2022等的編譯器。部分學(xué)校使用的vc6.0以及Devc++。前者是1998年推出的c語(yǔ)言編譯器,在現(xiàn)在的win10或者win11的系統(tǒng)中并不兼容,可能會(huì)出現(xiàn)一些問(wèn)題,后者也在2015年停更,這兩款祖?zhèn)鱟語(yǔ)言編譯器并不推薦使用,但是如果你們學(xué)校考試需要使用或者有明確要求,那當(dāng)我沒(méi)說(shuō)。
首先,我們要先創(chuàng)建一個(gè)項(xiàng)目,常見(jiàn)三個(gè)文件分別是頭文件game.h,源文件game.c,text.c。在這個(gè)game.h的頭文件中我們放入函數(shù)的聲明,定義常量以及頭文件的引用,在text.c文件中我們寫(xiě)入游戲進(jìn)行的程序,在game.c文件中我們寫(xiě)入實(shí)現(xiàn)游戲的函數(shù)。?
一、text.c源文件部分
1、main函數(shù)部分
因?yàn)槲覀兺嬉话延螒蚩隙ú贿^(guò)癮,我們要多玩幾把游戲,我們?cè)趖ext.c文件中的main函數(shù)里寫(xiě)入一個(gè)do while循環(huán)語(yǔ)句,實(shí)現(xiàn)多次進(jìn)行游戲。然后我們?cè)谘h(huán)語(yǔ)句中寫(xiě)入一個(gè)menu函數(shù)用來(lái)打印菜單。然后我們要在鍵盤(pán)上輸入一個(gè)值去判斷是否進(jìn)行游戲,這里使用一個(gè)switch分支。當(dāng)使用者輸入正確的輸入值時(shí)開(kāi)始進(jìn)行游戲。這里使用一個(gè)game函數(shù)實(shí)現(xiàn)游戲流程。
int main() { int n = 0; srand((size_t)time(NULL)); do { menu();//打印菜單 printf("請(qǐng)輸入 "); scanf("%d", &n); switch (n) { case 1:game(); break; case 0:printf("游戲結(jié)束\n"); break; default:printf("輸入錯(cuò)誤,請(qǐng)重新輸入!\n"); break; } } while (n != 0); }
main函數(shù)部分
?void menu() { printf("******************************************\n"); printf("******** 1.play *********\n"); printf("******** 0.exit *********\n"); printf("******************************************\n"); }
menu函數(shù)部分
2、game函數(shù)部分
在game函數(shù)中我們要實(shí)現(xiàn)游戲的主要流程,首先我們要打印一個(gè)3*3的棋盤(pán),大概是這樣的。
(在這里我們先把游戲的流程捋清楚,至于實(shí)現(xiàn)那些游戲步驟的函數(shù)我們放在后面game源文件部分去細(xì)說(shuō)。)
?因?yàn)槊總€(gè)格子在游戲開(kāi)始的時(shí)候都是空著的狀態(tài),而在玩家與電腦進(jìn)行游戲中是要輸入符號(hào)的,所以我們還要定義一個(gè)char型的二維數(shù)組,并初始化為‘? '。然后就是下棋階段,我們要連續(xù)下很多次棋所以說(shuō)這里使用一個(gè)while循環(huán)語(yǔ)句實(shí)現(xiàn),這里可以寫(xiě)成一個(gè)死循環(huán),當(dāng)后面的函數(shù)判斷到有玩家已經(jīng)勝出或者平局的時(shí)候使用break跳出循環(huán),因?yàn)椴徽撌请娔X還是玩家下棋后,我們要看到下到了哪里,所以說(shuō)我們要在玩家和電腦下棋后面再打印一次棋盤(pán)。每個(gè)人在下完棋之后,我們要判斷是否已經(jīng)勝利所以我們使用條件語(yǔ)句來(lái)判斷是否勝利,失敗或是平局。在配合循環(huán)我們基本游戲流程已經(jīng)寫(xiě)完了。
void game() { char board[ROW][COL];//定義一個(gè)二維數(shù)組。 initboard(board, ROW, COL);//初始化數(shù)組。 printboard(board, ROW, COL);//打印棋盤(pán)。 while (1) { //玩家下棋 playerboard(board, ROW, COL); //打印棋盤(pán) printboard(board, ROW, COL); //判斷是否勝利 if (iswinboard(board, ROW, COL) == '*') { printf("玩家勝利\n"); printf("********** 是否進(jìn)行下一局 **********\n"); printf("\n"); break; } else if (iswinboard(board, ROW, COL) == '#') { printf("電腦獲勝\n"); printf("********** 是否進(jìn)行下一局 **********\n"); printf("\n"); break; } else if (iswinboard(board, ROW, COL) == 'Q') { printf("平局\n"); printf("********** 是否進(jìn)行下一局 **********\n"); printf("\n"); break; } //電腦下棋 computermove(board, ROW, COL); //打印棋盤(pán) printboard(board, ROW, COL); //判斷是否勝利 if (iswinboard(board, ROW, COL) == '*') { printf("玩家勝利\n"); printf("********** 是否進(jìn)行下一局 **********\n"); printf("\n"); break; } else if (iswinboard(board, ROW, COL) == '#') { printf("電腦獲勝\n"); printf("********** 是否進(jìn)行下一局 **********\n"); printf("\n"); break; } else if (iswinboard(board, ROW, COL) == 'Q') { printf("平局\n"); printf("********** 是否進(jìn)行下一局 **********\n"); printf("\n"); break; } } }
game函數(shù)部分
二、game.h頭文件部分
#pragma once //在game頭文件里面去聲明函數(shù),定義常量。 #include<stdio.h> #include<stdlib.h> #include<time.h> //定義常量 #define ROW 3//這里通過(guò)更改ROW,COL的值來(lái)改變棋盤(pán)的大小 #define COL 3//可以更改成為n*n的棋盤(pán)。 //函數(shù)聲明 //打印棋盤(pán) void printboard(char board[ROW][COL], int row, int col); //初始化數(shù)組 void initboard(char board[ROW][COL], int row, int col); //玩家下棋//二維數(shù)組進(jìn)行函數(shù)傳參時(shí)可以不用寫(xiě)行數(shù) void playerboard(char board[][COL], int row, int col); //電腦下棋 void computermove(char board[ROW][COL], int row, int col); //判斷是否勝利 char iswinboard(char board[ROW][COL], int row, int col);
game.h部分
三、game.c源文件部分
還記得我們?cè)趖ext.c中使用了哪些函數(shù)嗎?
- 1、我們先要初始化二維數(shù)組
- 2、打印棋盤(pán)
- 3、玩家下棋
- 4、電腦下棋
- 5、判斷勝利
接下來(lái)的game.c文件就是要寫(xiě)入實(shí)現(xiàn)這幾個(gè)步驟的函數(shù)。
首先,初始化數(shù)組非常容易,兩個(gè)for循環(huán)即可。
//初始化數(shù)組元素 void initboard(char board[ROW][COL], int row, int col) { int i = 0, j = 0; //先對(duì)數(shù)組進(jìn)行賦值,因?yàn)槭莕*n的數(shù)組所以要賦值n*n次 //這里使用兩個(gè)for循環(huán)來(lái)實(shí)現(xiàn)。 for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { board[i][j] = ' '; } } }
初始化數(shù)組元素函數(shù)
然后是打印棋盤(pán)函數(shù)。
在打印棋盤(pán)中我們要注意,需要打印一行數(shù)組,一行“---”符號(hào)。在每一行的最后“|”不打印。在最下面一行“---|---|---”不打印,在這里我們只需要去控制for循環(huán)條件即可實(shí)現(xiàn),并不困難。
//打印棋盤(pán) void printboard(char board[ROW][COL], int row, int col) { int i = 0, 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 < row; j++) { printf("---"); if (j < row - 1) { printf("|"); } } } printf("\n"); } }
然后是玩家下棋函數(shù)
也就是對(duì)數(shù)組進(jìn)行賦值,因?yàn)橥婕也灰欢▽W(xué)過(guò)c語(yǔ)言,也不一定知道c語(yǔ)言中數(shù)組的下標(biāo)是從0開(kāi)始的,所以我們要對(duì)輸入的坐標(biāo)-1之后在進(jìn)行數(shù)組的相關(guān)操作。這里可以寫(xiě)上一個(gè)死循環(huán),當(dāng)玩家下出非法坐標(biāo)時(shí)提醒玩家重新下,當(dāng)玩家下出正確時(shí)再break跳出。
//玩家下棋函數(shù) void playerboard(char board[][COL], int row, int col) { int x = 0, y = 0; printf("請(qǐng)玩家下棋\n"); while (1)//這里可以寫(xiě)上一個(gè)死循環(huán),當(dāng)玩家下出非法坐標(biāo)時(shí)提醒玩家重新下。 //當(dāng)玩家下出正確時(shí)再break跳出。 { printf("請(qǐng)輸入坐標(biāo),請(qǐng)用空格隔開(kāi)。 \n"); scanf("%d %d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col)//判斷玩家下棋坐標(biāo)是否正確。 { if (board[x-1][y-1] == ' ') { board[x-1][y-1] = '*'; break; } else { printf("坐標(biāo)已被占用,請(qǐng)重新輸入!"); } } else { printf("坐標(biāo)非法,請(qǐng)重新輸入!"); } } }
再然后是電腦下棋
相較于玩家下棋電腦下棋就比較容易了,只用使用rand()%3隨機(jī)生成0-2之間的值,再判斷是否已被占用即可。
//電腦下棋 void computermove(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; printf("電腦下棋:>\n"); while (1) { x= rand() % ROW;//隨機(jī)取值如果放在循環(huán)外面則可能陷入死循環(huán)。 y= rand() % COL; if (board[x][y] == ' ') { board[x][y] = '#'; break; } } }
最后是判斷是否勝利的函數(shù)
這個(gè)比較長(zhǎng),但是基本就是if條件語(yǔ)句進(jìn)行判斷,分別判斷行、列、對(duì)角線以及平局。如果勝利成立則返回已連成線的其中一個(gè)格中的符號(hào)即可,這樣就不用再麻煩這判斷到底是電腦贏還是玩家贏了。返回到text.c中再進(jìn)行相應(yīng)的輸出。
//判斷是否勝利 char iswinboard(char board[ROW][COL], int row, int col) { int i = 0, j = 0, count = 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]; break; } } //判斷列是否勝利 for (j = 0; j < col; j++) { if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ') { return board[0][j]; break; } } //判斷對(duì)角線 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]; } //判斷是否平局 for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { if (board[i][j] == ' ') { count++; } } } if (count == 0) { return 'Q'; } return 'C'; }
這樣我們的一個(gè)三子棋游戲就寫(xiě)好了。你就可以發(fā)給朋友,或是自己私藏了。(steam是上不了了,自己玩玩算了。)
運(yùn)行
最后全部代碼放在這里
game.h
#pragma once //在game頭文件里面去聲明函數(shù),定義常量。 #include<stdio.h> #include<stdlib.h> #include<time.h> //定義常量 #define ROW 3//這里通過(guò)更改ROW,COL的值來(lái)改變棋盤(pán)的大小 #define COL 3//可以更改成為n*n的棋盤(pán)。 //函數(shù)聲明 //打印棋盤(pán) void printboard(char board[ROW][COL], int row, int col); //初始化數(shù)組 void initboard(char board[ROW][COL], int row, int col); //玩家下棋//二維數(shù)組進(jìn)行函數(shù)傳參時(shí)可以不用寫(xiě)行數(shù) void playerboard(char board[][COL], int row, int col); //電腦下棋 void computermove(char board[ROW][COL], int row, int col); //判斷是否勝利 char iswinboard(char board[ROW][COL], int row, int col);
text.c
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" void menu() { printf("******************************************\n"); printf("******** 1.play *********\n"); printf("******** 0.exit *********\n"); printf("******************************************\n"); } void game() { char board[ROW][COL];//定義一個(gè)二維數(shù)組。 initboard(board, ROW, COL);//初始化數(shù)組。 printboard(board, ROW, COL);//打印棋盤(pán)。 while (1) { //玩家下棋 playerboard(board, ROW, COL); //打印棋盤(pán) printboard(board, ROW, COL); //判斷是否勝利 if (iswinboard(board, ROW, COL) == '*') { printf("玩家勝利\n"); printf("********** 是否進(jìn)行下一局 **********\n"); printf("\n"); break; } else if (iswinboard(board, ROW, COL) == '#') { printf("電腦獲勝\n"); printf("********** 是否進(jìn)行下一局 **********\n"); printf("\n"); break; } else if (iswinboard(board, ROW, COL) == 'Q') { printf("平局\n"); printf("********** 是否進(jìn)行下一局 **********\n"); printf("\n"); break; } //電腦下棋 computermove(board, ROW, COL); //打印棋盤(pán) printboard(board, ROW, COL); //判斷是否勝利 if (iswinboard(board, ROW, COL) == '*') { printf("玩家勝利\n"); printf("********** 是否進(jìn)行下一局 **********\n"); printf("\n"); break; } else if (iswinboard(board, ROW, COL) == '#') { printf("電腦獲勝\n"); printf("********** 是否進(jìn)行下一局 **********\n"); printf("\n"); break; } else if (iswinboard(board, ROW, COL) == 'Q') { printf("平局\n"); printf("********** 是否進(jìn)行下一局 **********\n"); printf("\n"); break; } } } int main() { int n = 0; srand((size_t)time(NULL)); do { menu();//打印菜單 printf("請(qǐng)輸入 "); scanf("%d", &n); switch (n) { case 1:game(); break; case 0:printf("游戲結(jié)束\n"); break; default:printf("輸入錯(cuò)誤,請(qǐng)重新輸入!\n"); break; } } while (n != 0); }
game.c
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" //初始化數(shù)組元素 void initboard(char board[ROW][COL], int row, int col) { int i = 0, j = 0; //先對(duì)數(shù)組進(jìn)行賦值,因?yàn)槭莕*n的數(shù)組所以要賦值n*n次 //這里使用兩個(gè)for循環(huán)來(lái)實(shí)現(xiàn)。 for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { board[i][j] = ' '; } } } //打印棋盤(pán) void printboard(char board[ROW][COL], int row, int col) { int i = 0, 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 < row; j++) { printf("---"); if (j < row - 1) { printf("|"); } } } printf("\n"); } } //玩家下棋函數(shù) void playerboard(char board[][COL], int row, int col) { int x = 0, y = 0; printf("請(qǐng)玩家下棋\n"); while (1)//這里可以寫(xiě)上一個(gè)死循環(huán),當(dāng)玩家下出非法坐標(biāo)時(shí)提醒玩家重新下。 //當(dāng)玩家下出正確時(shí)再break跳出。 { printf("請(qǐng)輸入坐標(biāo),請(qǐng)用空格隔開(kāi)。 \n"); scanf("%d %d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col)//判斷玩家下棋坐標(biāo)是否正確。 { if (board[x-1][y-1] == ' ') { board[x-1][y-1] = '*'; break; } else { printf("坐標(biāo)已被占用,請(qǐng)重新輸入!"); } } else { printf("坐標(biāo)非法,請(qǐng)重新輸入!"); } } } //電腦下棋 void computermove(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; printf("電腦下棋:>\n"); while (1) { x= rand() % ROW;//隨機(jī)取值如果放在循環(huán)外面則可能陷入死循環(huán)。 y= rand() % COL; if (board[x][y] == ' ') { board[x][y] = '#'; break; } } } //判斷是否勝利 char iswinboard(char board[ROW][COL], int row, int col) { int i = 0, j = 0, count = 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]; break; } } //判斷列是否勝利 for (j = 0; j < col; j++) { if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ') { return board[0][j]; break; } } //判斷對(duì)角線 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]; } //判斷是否平局 for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { if (board[i][j] == ' ') { count++; } } } if (count == 0) { return 'Q'; } return 'C'; }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
OpenMP?Parallel?Construct的實(shí)現(xiàn)原理詳解
在本篇文章當(dāng)中我們將主要分析?OpenMP?當(dāng)中的?parallel?construct?具體時(shí)如何實(shí)現(xiàn)的,以及這個(gè)?construct?調(diào)用了哪些運(yùn)行時(shí)庫(kù)函數(shù),并且詳細(xì)分析這期間的參數(shù)傳遞,需要的可以參考一下2023-01-01Windows程序內(nèi)部運(yùn)行機(jī)制實(shí)例詳解
這篇文章主要介紹了Windows程序內(nèi)部運(yùn)行機(jī)制實(shí)例詳解,對(duì)于學(xué)習(xí)Windows程序設(shè)計(jì)來(lái)說(shuō)是非常重要的一課,需要的朋友可以參考下2014-08-08C語(yǔ)言中對(duì)文件最基本的讀取和寫(xiě)入函數(shù)
這篇文章主要介紹了C語(yǔ)言中對(duì)文件最基本的讀取和寫(xiě)入函數(shù),是C語(yǔ)言入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-08-08C 語(yǔ)言基礎(chǔ)教程(我的C之旅開(kāi)始了)[六]
C 語(yǔ)言基礎(chǔ)教程(我的C之旅開(kāi)始了)[六]...2007-02-02詳細(xì)解析C語(yǔ)言中的開(kāi)方實(shí)現(xiàn)
這篇文章主要介紹了詳細(xì)解析C語(yǔ)言中的開(kāi)方實(shí)現(xiàn),包括一道要求精度的整數(shù)開(kāi)方的題目,需要的朋友可以參考下2015-08-08C++圖解單向鏈表類(lèi)模板和iterator迭代器類(lèi)模版詳解
這篇文章主要為大家詳細(xì)介紹了C++圖解單向鏈表類(lèi)模板和iterator迭代器類(lèi)模版,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-02-02