一盤(pán)王者的時(shí)間用C語(yǔ)言實(shí)現(xiàn)三子棋
1.先進(jìn)行環(huán)境的配置
一共會(huì)用到三個(gè)文件,分別是兩個(gè)源文件test.c game.c ,還有一個(gè)頭文件game.h
他們的關(guān)系分別是:
test.c是主體,是游戲的測(cè)試邏輯
game.c是游戲的實(shí)現(xiàn)邏輯
game.h是實(shí)現(xiàn)游戲函數(shù)的聲明
也就是說(shuō),main函數(shù)在test.c文件中,游戲的實(shí)現(xiàn)會(huì)使用一部分函數(shù),而函數(shù)的功能的實(shí)現(xiàn)主要是在game.c函數(shù)里,主體文件中使用時(shí)引用即可。game.c函數(shù)中主要是為了函數(shù)的聲明。說(shuō)到這里,你是不是有疑惑,為什么要?jiǎng)?chuàng)建這么多的文件,事實(shí)上,如果要實(shí)現(xiàn)三子棋的看功能的實(shí)現(xiàn)的確只需要一個(gè)test.c就可以完成。但是分開(kāi)能夠很好區(qū)分各自的功能,防止文件的內(nèi)容過(guò)于繁瑣,不便觀察。這樣就能更好的理解。
2.各種功能實(shí)現(xiàn)的邏輯關(guān)系
游戲的實(shí)現(xiàn)大致流程是:
1.實(shí)現(xiàn)游戲的開(kāi)始退出流程
2.創(chuàng)建一個(gè)名為board的二維數(shù)組,并進(jìn)行初始化
3.棋盤(pán)的搭建
4.玩家下棋,并打印新的棋盤(pán)
5.電腦下棋,并打印新的棋盤(pán)
6.判斷結(jié)果
2.1實(shí)現(xiàn)游戲的開(kāi)始退出流程
便于分析,我把各部分的功能分解,所有的功能全部放在test函數(shù)中來(lái)實(shí)現(xiàn)。
int main() { test(); return 0; }
打印一個(gè)菜單。
void menu() { printf("**************************\n"); printf("****** 1.star **********\n"); printf("****** 0.exit **********\n"); printf("**************************\n"); }
玩家選擇開(kāi)始游戲與退出游戲選擇的實(shí)現(xiàn)
void test() { int input = 0; do { menu(); printf("請(qǐng)輸入開(kāi)始或者退出:"); scanf("%d", &input); switch (input) { case(1): game(); break; case(0): printf("退出游戲\n"); break; default: printf("選擇錯(cuò)誤,請(qǐng)重新選擇\n"); break; } } while (input); } int main() { test(); return 0; }
2.2 創(chuàng)建一個(gè)名為board的二維數(shù)組,并進(jìn)行初始化
創(chuàng)造一個(gè)二維數(shù)組,初始話數(shù)組,實(shí)現(xiàn)程序的大體框架
char board[ROW][COL] = { 0 };
void InitBoard(char board[ROW][COL], int row, int col)//初始化數(shù)組 { int i, j; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { board[i][j] = ' '; } } }
2.3 棋盤(pán)的搭建
首先是在game.c文件中,實(shí)現(xiàn)棋盤(pán)搭建的功能
void DisplayBoard(char board[ROW][COL], int row, int col) { int i = 0; int j = 0; for (i = 0; i < row; i++) { //數(shù)據(jù) 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"); } }
然后就在test.c文件調(diào)用
InitBoard(board, ROW, COL);
這一點(diǎn)是一個(gè)關(guān)鍵,棋盤(pán)的搭建,要留有數(shù)據(jù)的空間,以便于游戲開(kāi)始時(shí),玩家或電腦在棋盤(pán)上進(jìn)行操作。還有每一行有一個(gè)分割線,且要保證每一行的區(qū)分,還有每一豎的分界線,要保證元素分割開(kāi),創(chuàng)建一個(gè)“井”子框架。
2.4 玩家下棋,并打印新的棋盤(pán)
在game文件中實(shí)現(xiàn)玩家在棋盤(pán)上的空位進(jìn)行判斷,并選擇一個(gè)位置在上面打印出你自己選擇的符號(hào),并打印出你在上面操作之后的棋盤(pán)。
void Player_move(char board[ROW][COL], int row, int col) { int x, y; while (1) { printf("請(qǐng)選擇坐標(biāo):\n"); 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("坐標(biāo)被占,請(qǐng)重新上輸入\n"); } else { printf("坐標(biāo)非法,請(qǐng)重新輸入\n"); } } }
2.5 電腦下棋,并打印新的棋盤(pán)
玩家選擇一個(gè)位置打印符號(hào)后,這時(shí)候就要用rand函數(shù)產(chǎn)生一個(gè)隨機(jī)數(shù),并指定隨機(jī)數(shù)的范圍,再隨機(jī)產(chǎn)生一個(gè)坐標(biāo)。電腦自動(dòng)選擇一個(gè)空位置隨機(jī)打印另一個(gè)符號(hào),并重新打印出新的棋盤(pán)。(如果以后有機(jī)會(huì),希望自己寫(xiě)一個(gè)比較厲害的算法 哈哈)
void computer_move(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; } } }
2.6.判斷結(jié)果
再進(jìn)行多次玩家--電腦--玩家--電腦的循環(huán)之后,就會(huì)出現(xiàn)一個(gè)結(jié)果,這時(shí)候就要對(duì)結(jié)果進(jìn)行分析,當(dāng)三個(gè)相同的符號(hào)連在一起時(shí),這些情況包括行豎,還有對(duì)角線。如果三符號(hào)相同,就會(huì)出現(xiàn)一個(gè)結(jié)果。當(dāng)然,當(dāng)全部下滿時(shí),就會(huì)產(chǎn)生一個(gè)平局。代碼的實(shí)現(xiàn)如下:
//判斷輸贏 if (ret != 'C') { break; } computer_move(board, ROW, COL); DisplayBoard(board, ROW, COL); ret = is_win(board, ROW, COL); if (ret != 'C') { break; } } if (ret == '*') { printf("玩家贏\n"); } else if (ret == '#') { printf("電腦贏\n"); } else { printf("平局\n"); } }
創(chuàng)建一個(gè) is_win函數(shù),并返回一個(gè)符號(hào),判斷結(jié)果
返回的符號(hào)分別表示:
玩家贏:*
電腦贏:#
平局:Q;
繼續(xù):C;
char is_win(char board[ROW][COL], int row, int col) { //當(dāng)玩家或者電腦有三行 int i = 0; for (i = 0; i < row; i++) { if(board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ') return board[i][0]; } //縱 for (i = 0; i < col; i++) { if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ') { return board[1][i]; } } //對(duì)角線的判斷 if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') { return board[1][1]; } if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ') { return board[1][1]; } //判斷平局 if (1 == is_full(board, row, col)) { return 'Q'; } //繼續(xù) return 'C'; }
當(dāng)棋盤(pán)下滿時(shí),若為分出勝負(fù),就會(huì)使用is_full函數(shù),并返回相應(yīng)符號(hào),結(jié)果就是平局。
int is_full(char board[ROW][COL], int row, int col)//對(duì)平局的判斷 { 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; }
3.程序?qū)崿F(xiàn)的代碼
3.1 text.c
#define _CRT_SECURE_NO_WARNINGS 1 //游戲的開(kāi)發(fā)邏輯 #include"game.h" void game() { //假設(shè)玩家下的棋子是*,電腦下的是# char board[ROW][COL] = { 0 };//數(shù)組的內(nèi)容應(yīng)該全部是空格 //初始化棋盤(pán) InitBoard(board, ROW, COL); //打印棋盤(pán) DisplayBoard(board, ROW, COL); //玩家下棋 char ret = 0; while (1) { srand((unsigned)time(NULL)); Player_move(board, ROW, COL); DisplayBoard(board, ROW, COL); ret = is_win(board, ROW, COL); //判斷輸贏 if (ret != 'C') { break; } computer_move(board, ROW, COL); DisplayBoard(board, ROW, COL); ret = is_win(board, ROW, COL); if (ret != 'C') { break; } } if (ret == '*') { printf("玩家贏\n"); } else if (ret == '#') { printf("電腦贏\n"); } else { printf("平局\n"); } } void menu() { printf("**************************\n"); printf("****** 1.star **********\n"); printf("****** 0.exit **********\n"); printf("**************************\n"); } void test() { int input = 0; do { menu(); printf("請(qǐng)輸入開(kāi)始或者退出:"); scanf("%d", &input); switch (input) { case(1): game(); break; case(0): printf("退出游戲\n"); break; default: printf("選擇錯(cuò)誤,請(qǐng)重新選擇\n"); break; } } while (input); } int main() { test(); return 0; }
3.2 game.h
#pragma once #define _CRT_SECURE_NO_WARNINGS 1 //游戲?qū)崿F(xiàn)函數(shù)的聲明 #include<stdio.h> #define ROW 3 #define COL 3 #include<time.h> #include <stdlib.h> void InitBoard(char board[ROW][COL], int row, int col);//初始化函數(shù) void DisplayBoard(char board[ROW][COL], int row, int col);//展示棋盤(pán) void Player_move(char board[ROW][COL], int row, int col);//玩家下棋 void computer_move(char board[ROW][COL], int row, int col);//電腦下棋 char is_win(char board[ROW][COL], int row, int col);
3.3 game.c
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" //游戲的實(shí)現(xiàn)邏輯 int is_full(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; } void InitBoard(char board[ROW][COL], int row, int col)//初始化數(shù)組 { int i, j; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { board[i][j] = ' '; } } } //打印棋盤(pán) void DisplayBoard(char board[ROW][COL], int row, int col) { int i = 0; int j = 0; for (i = 0; i < row; i++) { //數(shù)據(jù) 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 Player_move(char board[ROW][COL], int row, int col) { int x, y; while (1) { printf("請(qǐng)選擇坐標(biāo):\n"); 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("坐標(biāo)被占,請(qǐng)重新上輸入\n"); } else { printf("坐標(biāo)非法,請(qǐng)重新輸入\n"); } } } void computer_move(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; } } } char is_win(char board[ROW][COL], int row, int col) { //當(dāng)玩家電腦有三行 int i = 0; for (i = 0; i < row; i++) { if(board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ') return board[i][0]; } //縱 for (i = 0; i < col; i++) { if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ') { return board[1][i]; } } //對(duì)角線的判斷 if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') { return board[1][1]; } if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ') { return board[1][1]; } //判斷平局 if (1 == is_full(board, row, col)) { return 'Q'; } //繼續(xù) return 'C'; }
到此這篇關(guān)于一盤(pán)王者的時(shí)間用C語(yǔ)言實(shí)現(xiàn)三子棋的文章就介紹到這了,更多相關(guān)C語(yǔ)言 三子棋內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)LeetCode(36.驗(yàn)證數(shù)獨(dú))
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(36.驗(yàn)證數(shù)獨(dú)),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C語(yǔ)言中的for循環(huán)語(yǔ)句基本語(yǔ)法及使用
這篇文章主要介紹了C語(yǔ)言中的for循環(huán)語(yǔ)句基本語(yǔ)法及使用,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06在while中使用cin>>a?為條件及注意事項(xiàng)說(shuō)明
這篇文章主要介紹了在while中使用cin>>a?為條件及注意事項(xiàng)說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07用VC++6.0實(shí)現(xiàn)石頭剪刀布游戲的程序
最先看到這個(gè)游戲代碼是python版的,后來(lái)看到有小伙伴用VC++重寫(xiě)了一遍,運(yùn)行之后發(fā)現(xiàn)有些小bug,便嘗試這修復(fù)了一下,并增加了些小功能,這里分享給大家。2015-03-03C++-操作符重載、并實(shí)現(xiàn)復(fù)數(shù)類詳解
這篇文章主要介紹了C++-操作符重載、并實(shí)現(xiàn)復(fù)數(shù)類,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03基于Windows API實(shí)現(xiàn)遍歷所有文件并刪除的方法
這篇文章主要介紹了基于Windows API實(shí)現(xiàn)遍歷所有文件并刪除的方法,是win32應(yīng)用程序的一個(gè)比較典型的文件操作應(yīng)用技巧,需要的朋友可以參考下2015-04-04解析C++中的for循環(huán)以及基于范圍的for語(yǔ)句使用
這篇文章主要介紹了解析C++中的for循環(huán)以及基于范圍的for語(yǔ)句使用,是C++入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-01-01C++基于Directx MMX實(shí)現(xiàn)的圖像灰度轉(zhuǎn)換代碼
這篇文章主要介紹了C++基于Directx MMX實(shí)現(xiàn)的圖像灰度轉(zhuǎn)換代碼,需要的朋友可以參考下2014-08-08