井字棋(C语言实现,可运行玩耍,自行编写)
井字棋,英文名叫Tic-Tac-Toe,是一種在3*3格子上進行的連珠游戲,和五子棋類似,由于棋盤一般不畫邊框,格線排成井字故得名。游戲需要的工具僅為紙和筆,然后由分別代表O和X的兩個游戲者輪流在格子里留下標記(一般來說先手者為X),任意三個標記形成一條直線,則為獲勝。
很簡單,就是在畫一個井圖形里面畫符號,誰先到3個就贏了.
試想一下,我們第一步肯定是需要讀入輸入的符號,我們用 X? 和? O? 代替.?
那記錄判斷我們是否贏了的方法, 需要用到數組和遍歷
然后就是判斷結果.就可以了.
?
下面開始實施階段:
按照我們理想化的步驟來實現
第一步
我們是想要如圖的圖案,那就輸入回車和制表符,很簡單,但是不定長的數字就不好控制了,所以我們用
for循環依次輸出:
printf("\t 0 \t 1 \t 2 \t\n\n");for(int i=0;i<3;i++){printf(" %d\t ___\t___\t___\t\n\n",i);}第二步:實現輸入字符
?需要我們用數組保存我們輸入的坐標地址
定義數組
int board[size][size];等玩家輸入對應坐標后,對二維數組的值進行對應賦值,
printf("玩家一請輸入坐標\n");scanf("%d %d",&i,&j);board[i][j]=1;printf("請玩家二輸入坐標\n");scanf("%d %d",&i,&j);board[i][j]=0;我們會根據對應的數組的值進行遍歷,是我們需要的就賦值對應圖形的形狀? X? ?O
遍歷的話都是一樣的,同樣道理,這里列出來一個
for(int i=0; i<size;i++){for(int j=0;j<size; j++ ){if(board[i][j]==1){printf("_X_");ope++;if(ope%size==0){if(ope/size==size){printf("\n\n\n");}else if(ope/size<size){printf("\n\n\n %d\t",ope/size);}}else{printf("\t");} }else if(board[i][j]==-1){printf("___");ope++;if(ope%size==0){if(ope/size==size){printf("\n\n\n");}else if(ope/size<size){printf("\n\n\n %d\t",ope/size);}}else{printf("\t");}}else if(board[i][j] == 0){printf("_O_");ope++;if(ope%size==0){if(ope/size==size){printf("\n\n\n");}else if(ope/size<size){printf("\n\n\n %d\t",ope/size);}}else{printf("\t");}}}}根據不同的數,進行不同的賦值
然后我們可以根據輸入對應的坐標進行游戲了
第三步:判斷輸贏家.?
那如何讓電腦判定誰贏了呢?
接下來,就是遍歷,計數每一行,每一列,正對角線,副對角線是否出現同樣圖案一條線的了,玩家一先劃
,接著玩家二畫圖案.
我們可以根據玩家輸入的數字進行對對應的二維數組賦值,然后分三次遍歷計數,
第一次,先確定一行,遍歷列,這樣就把每一行便利判斷完了
//檢查行for (int i=0; i<size ; i++ ){numofo=0;numofx=0;for( j=0; j<size; j++ ){if( board[i][j] == 1){numofx++;// printf("numofx的值是:%d\n",numofx);}else if(board[i][j]==0){numofo++;// printf("numofo的值是:%d\n",numofo);}else{}}if(numofo == size){result = 0;cnt_o++;} else if(numofx == size) {result =1;cnt_x++;} else{result =-1;}}第二次,和第一次差不多,調換了以下順序,先確定列,遍歷行,逐漸加一,直到把所有的列遍歷完
//檢查列for( j=0; j<size ; j++){numofo = numofx = 0;for( i=0; i<size; i++){if( board[i][j] == 1){numofx ++;}else if(board[i][j]==0) {numofo ++;}}if(numofo == size){result = 0;cnt_o++; }else if(numofx == size){result = 1;cnt_x++;}}第三次,正對角線
每次的行號和列號是相等的
//正對角線numofo = numofx = 0;for(i=0; i<size; i++){if( board[i][i] == 1){numofx ++;}else if(board[i][j]==0) {numofo ++;}}if( numofo == size){result = 0;cnt_o++;}else if( numofx == size){result = 1;cnt_x++;}// printf("3.檢查的正對角線\n cnt_o值是:%d\n cnt_x值是:%d\n",cnt_o,cnt_x);//斜對角線numofo = numofx = 0;for( i=0; i<size; i++ ){if( board[i][size-i-1] == 1){numofx++;}else if( board[i][size-i-1] == 0){numofo++;}}if( numofo == size){result = 0;cnt_o++;}else if(numofx == size){result = 1;cnt_x++;}第四次,斜對角線
和正對角線不同的是, 斜對角線對應數組行列不一樣.
具體的話,驗算一下,相對于正對角線,加了一個size,但是我們是從0計算坐標的,所以再減去1,對比一下, 就知道了:
board[i][size - i - 1]
numofo = numofx = 0;for( i=0; i<size; i++ ){if( board[i][size-i-1] == 1){numofx++;}else if( board[i][size-i-1] == 0){numofo++;}}if( numofo == size){result = 0;cnt_o++;}else if(numofx == size){result = 1;cnt_x++;}檢查完了后,如何判斷是否夠一條線呢?? 就是在每次判斷同樣圖案后,加一個計數器
當等于一條線的長度時,就對對應的數加一,這樣我們就可以判斷, 游戲是否結束, 并且誰獲勝,或者是平局了
if( numofo == size){?? ??? ??? ?result = 0;
?? ??? ??? ?cnt_o++;
?? ??? ?}else if(numofx == size){
?? ??? ??? ?result = 1;
?? ??? ??? ?cnt_x++;
?? ??? ?}
第六步:就是判斷游戲結束
當游戲的九個空格輸入完前,? 判斷游戲是否結束,? 我們的游戲是否繼續,我們使用嵌套
do{
}
while(cnt_o==0 && cnt_x==0 &&count<(size*size-1)/2);
第七步:? 根據具體計數器的結果, 判斷誰勝誰負
if(cnt_x==1 && cnt_o==0&& count<=(size*size-1)/2){
?? ??? ?printf("恭喜玩家一,你贏啦!\n");
?? ?}else if(cnt_o==1 && cnt_x==0){
?? ??? ?printf("恭喜玩家二,你贏啦!\n");
?? ?}else if(cnt_o==0 &&cnt_x==0 && count==(size*size-1)/2){
?? ??? ?printf("恭喜雙方打成平局,以和為貴!");
?? ?}else if(cnt_o==1 &&cnt_x==1 ){
?? ??? ?printf("恭喜你們雙贏啦!\n");
?? ??? ?printf("請按回車鍵繼續:\n");
?? ??? ?getchar();getchar();
?? ??? ?printf("開個玩笑,其實是 玩家一 贏了!\n");
?? ?}
第八步,其實現在大概已經實現了
但是還有幾個小改進,需要注意一下
①如果我們想要讓玩家每次輸入對應坐標后,? 就可以看見對應符號在數組中的位置,? 就需要剛開始第一部輸入的表格, 然后我們接著遍歷輸入對應的符號就可以了.
②因為我們判斷游戲結束, 是當兩個人都輸入完后才判斷的,? 有一種情況是,? 玩家一最后才輸入完,
然后格子占滿了,? 玩家二不用輸入了,仍然會出現讓玩家二輸入的情況.? ?
我們的解決辦法是, 在玩家二輸入后邊 加了一個計數器,? 當?
while(cnt_o==0 && cnt_x==0 &&count<(size*size-1)/2);
?當玩家二輸入4次時候,? 如果判斷沒有玩家贏的話,? 需要玩家一接著輸入一次
所以我們 在玩家二輸入四次的時候,? 就跳出循環, 給玩家一,? 單獨來一個套娃,? (這里作者能力有限,只能套娃)? ,就是把前面的重新拷貝一下,? 把玩家二的刪除救行了.? ?這里就解決了最后一次不能輸入的問題
源代碼奉上:
#include <stdio.h>int main(int argc, char *argv[]) {const int size = 3;int board[size][size];int i,j;int numofx=0;int numofo=0;int result=-1; //-1:沒人贏,1:x贏, 0:0贏int cnt_o=0;int cnt_x=0;int count=0;for( i=0; i<size; i++){for( j=0; j<size; j++){board[i][j]=-1;}}// printf("%d",board[2][2]);//讀入矩陣printf("\t 0 \t 1 \t 2 \t\n\n");for(int i=0;i<3;i++){printf(" %d\t ___\t___\t___\t\n\n",i);}do {//printf("游戲還未結束,請繼續:\n");printf("玩家一請輸入坐標\n");scanf("%d %d",&i,&j);printf("\n");printf("\t");for(int k=0;k<size;k++){printf("%d \t",k);}// printf("\t 0 \t 1 \t 2 \t");printf("\n\n");printf(" 0 \t");board[i][j]=1;int ope=0;for(int i=0; i<size;i++){for(int j=0;j<size; j++ ){if(board[i][j]==1){printf("_X_");ope++;if(ope%size==0){if(ope/size==size){printf("\n\n\n");}else if(ope/size<size){printf("\n\n\n %d\t",ope/size);}}else{printf("\t");} }else if(board[i][j]==-1){printf("___");ope++;if(ope%size==0){if(ope/size==size){printf("\n\n\n");}else if(ope/size<size){printf("\n\n\n %d\t",ope/size);}}else{printf("\t");}}else if(board[i][j] == 0){printf("_O_");ope++;if(ope%size==0){if(ope/size==size){printf("\n\n\n");}else if(ope/size<size){printf("\n\n\n %d\t",ope/size);}}else{printf("\t");}}}}// printf("board[%d][%d]=%d\n",i,j,board[i][j]);printf("請玩家二輸入坐標\n");scanf("%d %d",&i,&j);count++;printf("\n");printf("\t");for(int k=0;k<size;k++){printf("%d \t",k);}// printf("\t 0 \t 1 \t 2 \t");printf("\n\n");printf(" 0 \t");board[i][j]=0;int opes=0;for(int i=0; i<size;i++){for(int j=0;j<size; j++ ){if(board[i][j]==1){printf("_X_");opes++;if(opes%size==0){if(opes/size==size){printf("\n\n\n");}else if(opes/size<size){printf("\n\n\n %d\t",opes/size);}}else{printf("\t");} }else if(board[i][j]==-1){printf("___");opes++;if(opes%size==0){if(opes/size==size){printf("\n\n\n");}else if(opes/size<size){printf("\n\n\n %d\t",opes/size);}}else{printf("\t");}}else if(board[i][j] == 0){printf("_O_");opes++;if(opes%size==0){if(opes/size==size){printf("\n\n\n");}else if(opes/size<size){printf("\n\n\n %d\t",opes/size);}}else{printf("\t");}}}}// printf("board[%d][%d]=%d\n",i,j,board[i][j]);// printf("%d",board[2][2]);//檢查行for (int i=0; i<size ; i++ ){numofo=0;numofx=0;for( j=0; j<size; j++ ){if( board[i][j] == 1){numofx++;// printf("numofx的值是:%d\n",numofx);}else if(board[i][j]==0){numofo++;// printf("numofo的值是:%d\n",numofo);}else{}}if(numofo == size){result = 0;cnt_o++;} else if(numofx == size) {result =1;cnt_x++;} else{result =-1;}}// printf("1.檢查的行\n cnt_o值是:%d\ncnt_x值是:%d\n",cnt_o,cnt_x);//檢查列for( j=0; j<size ; j++){numofo = numofx = 0;for( i=0; i<size; i++){if( board[i][j] == 1){numofx ++;}else if(board[i][j]==0) {numofo ++;}}if(numofo == size){result = 0;cnt_o++; }else if(numofx == size){result = 1;cnt_x++;}}// printf("2.檢查的列\n cnt_o值是:%d\ncnt_x值是:%d\n",cnt_o,cnt_x);//正對角線numofo = numofx = 0;for(i=0; i<size; i++){if( board[i][i] == 1){numofx ++;}else if(board[i][j]==0) {numofo ++;}}if( numofo == size){result = 0;cnt_o++;}else if( numofx == size){result = 1;cnt_x++;}// printf("3.檢查的正對角線\n cnt_o值是:%d\n cnt_x值是:%d\n",cnt_o,cnt_x);//斜對角線numofo = numofx = 0;for( i=0; i<size; i++ ){if( board[i][size-i-1] == 1){numofx++;}else if( board[i][size-i-1] == 0){numofo++;}}if( numofo == size){result = 0;cnt_o++;}else if(numofx == size){result = 1;cnt_x++;}// printf("4.檢查的斜對角線\n cnt_o值是:%d\ncnt_x值是:%d\n",cnt_o,cnt_x);}while(cnt_o==0 && cnt_x==0 &&count<(size*size-1)/2);//int count=9;if(cnt_x==0 && cnt_o==0 && count==(size*size-1)/2){do {//printf("游戲還未結束,請繼續:\n");printf("玩家一請輸入坐標\n");scanf("%d %d",&i,&j);printf("\n");printf("\t");for(int k=0;k<size;k++){printf("%d \t",k);}// printf("\t 0 \t 1 \t 2 \t");printf("\n\n");printf(" 0 \t");board[i][j]=1;int ope=0;for(int i=0; i<size;i++){for(int j=0;j<size; j++ ){if(board[i][j]==1){printf("_X_");ope++;if(ope%size==0){if(ope/size==size){printf("\n\n\n");}else if(ope/size<size){printf("\n\n\n %d\t",ope/size);}}else{printf("\t");} }else if(board[i][j]==-1){printf("___");ope++;if(ope%size==0){if(ope/size==size){printf("\n\n\n");}else if(ope/size<size){printf("\n\n\n %d\t",ope/size);}}else{printf("\t");}}else if(board[i][j] == 0){printf("_O_");ope++;if(ope%size==0){if(ope/size==size){printf("\n\n\n");}else if(ope/size<size){printf("\n\n\n %d\t",ope/size);}}else{printf("\t");}}}}//檢查行for (int i=0; i<size ; i++ ){numofo=0;numofx=0;for( j=0; j<size; j++ ){if( board[i][j] == 1){numofx++;// printf("numofx的值是:%d\n",numofx);}else if(board[i][j]==0){numofo++;// printf("numofo的值是:%d\n",numofo);}else{}}if(numofo == size){result = 0;cnt_o++;} else if(numofx == size) {result =1;cnt_x++;} else{result =-1;}}// printf("1.檢查的行\n cnt_o值是:%d\ncnt_x值是:%d\n",cnt_o,cnt_x);//檢查列for( j=0; j<size ; j++){numofo = numofx = 0;for( i=0; i<size; i++){if( board[i][j] == 1){numofx ++;}else if(board[i][j]==0) {numofo ++;}}if(numofo == size){result = 0;cnt_o++; }else if(numofx == size){result = 1;cnt_x++;}}// printf("2.檢查的列\n cnt_o值是:%d\ncnt_x值是:%d\n",cnt_o,cnt_x);//正對角線numofo = numofx = 0;for(i=0; i<size; i++){if( board[i][i] == 1){numofx ++;}else if(board[i][j]==0) {numofo ++;}}if( numofo == size){result = 0;cnt_o++;}else if( numofx == size){result = 1;cnt_x++;}// printf("3.檢查的正對角線\n cnt_o值是:%d\n cnt_x值是:%d\n",cnt_o,cnt_x);//斜對角線numofo = numofx = 0;for( i=0; i<size; i++ ){if( board[i][size-i-1] == 1){numofx++;}else if( board[i][size-i-1] == 0){numofo++;}}if( numofo == size){result = 0;cnt_o++;}else if(numofx == size){result = 1;cnt_x++;}// printf("4.檢查的斜對角線\n cnt_o值是:%d\ncnt_x值是:%d\n",cnt_o,cnt_x);}while(cnt_o==0 && cnt_x==0 &&count<(size*size-1)/2);}if(cnt_x==1 && cnt_o==0&& count<=(size*size-1)/2){printf("恭喜玩家一,你贏啦!\n");}else if(cnt_o==1 && cnt_x==0){printf("恭喜玩家二,你贏啦!\n");}else if(cnt_o==0 &&cnt_x==0 && count==(size*size-1)/2){printf("恭喜雙方打成平局,以和為貴!");}else if(cnt_o==1 &&cnt_x==1 ){printf("恭喜你們雙贏啦!\n");printf("請按回車鍵繼續:\n");getchar();getchar();printf("開個玩笑,其實是 玩家一 贏了!\n");}return 0; }總結
以上是生活随笔為你收集整理的井字棋(C语言实现,可运行玩耍,自行编写)的全部內容,希望文章能夠幫你解決所遇到的問題。