算法思想:
这种方法可以实现:三子棋、五子棋、、、任意你想玩的棋子个数,棋盘规模也任意调整,相比较前一个使用范围广,更优化;具体实现内容上与上一个的区别是:(1)在初始化棋盘上比较细微,将棋盘的每个格子又划分为3*3的小格,再用大格表示小格
(2)判断输赢时候,不是上一种的枚举可能赢得结果类型,而是以某个点为研究对象,分别计算出行(左加右)、列(上加下)、对角线上所有相同字符个数,若总和大于等于
要玩 的棋子个数,则赢。正是这种方法实现了三子棋、五子棋、、、所有子棋的效果
头文件game.h
#ifndef __GAME_H__
#define __GAME_H__
#define ROW 10 //宏定义棋盘规模
#define COL 10
#define BOARD 5 //宏定义要玩的棋子个数(三子棋、五子棋...)
void init_board(char board[][4*COL+1],int row,int col); //初始化棋盘
void display_board(char board[][4*COL+1],int row,int col); //打印棋盘
void player_move(char a[][4*COL+1],int row,int col); //玩家落子
void computer_move(char a[][4*COL+1],int row,int col); //电脑落子
int check_win(char a[][4*COL+1],int row,int col); //判断输赢
#endif //__GAME_H__
#include "game1.h"
//初始化棋盘,这里把每一个位置又分为3*3的小格,使得棋盘更美观
void init_board(char board[][4*COL+1],int row,int col)
{
int i,j;
for(i=0;i < row;i+=2)
{
for(j=0;j < col;++j)
{
board[i][j] = '-';
}
}
for(i=1;i < row;i+=2)
{
for(j=0;j < col;j+=4)
{
board[i][j] = '|';
}
}
}
//打印棋盘
void display_board(char board[][4*COL+1],int row,int col)
{
int i,j;
for(i=0;i <row;++i)
{
for(j=0;j <col;++j)
{
printf("%c",board[i][j]);
}
printf("\n");
}
}
//玩家落子
void player_move(char a[][4*COL+1],int row,int col)
{
row = 2*row-1;
col = 2+4*(col-1);
a[row][col] = 'X';
}
//电脑落子
void computer_move(char a[][4*COL+1],int row,int col)
{
row = 2*(row+1)-1;
col = 2+4*col;
a[row][col] = 'O';
}
//判断输赢
int check_win(char a[][4*COL+1],int row,int col)
{
int count = 1;
char star;
int rowt,colt;
row = 2*(row+1)-1;
col = 2+4*col;
star = a[row][col];
for(rowt=row-2;rowt>=0 && a[rowt][col]==star;rowt-=2)
{
++count;
}
for(rowt=row+2;rowt<2*ROW+1 && a[rowt][col]==star;rowt+=2)
{
++count;
}
if(count >= BOARD) //上下连通区域个数大于等于3,说明赢
{
return 1;
}
count=1; //换方向检测时,将计数器个数重置1
for(colt=col-4;colt>=0 && a[row][colt]==star;colt-=4) //检测左右方向
{
++count;
}
for(colt=col+4;colt<4*COL+1 && a[row][colt]==star;colt+=4)
{
++count;
}
if(count >= BOARD) //如果该方向的连着的字符大于等于要玩的棋子个数,说明赢
{
return 1;
}
count=1; //判断完毕之后,将计数器count 重置1
for(rowt=row-2,colt=col-4;rowt>=0 && a[rowt][colt]==star && colt>=0;rowt-=2,colt-=4) //检测交叉线
{
++count;
}
for(rowt=row+2,colt=col+4;rowt<2*ROW+1 && a[rowt][colt]==star && colt<4*COL+1;rowt+=2,colt+=4)
{
++count;
}
if(count >= BOARD)
{
return 1;
}
count = 1;
for(rowt=row-2,colt=col+4;rowt>=0 && a[rowt][colt]==star && colt<4*COL+1;rowt-=2,colt+=4) //检测交叉线
{
++count;
}
for(rowt=row+2,colt=col-4;rowt<2*ROW+1 && a[rowt][col]==star && colt>=0;rowt+=2,colt-=4)
{
++count;
}
if(count >= BOARD)
{
return 1;
}
return 0;
}
#include <stdio.h>
#include "game1.h"
void menu()
{
printf("**********************\n");
printf("**** %d子棋游戏 *******\n",BOARD); //选择玩 几 子棋
printf("**** 1.play ********\n");
printf("**** 0.exit ********\n");
printf("**********************\n");
}
enum Option //枚举类型供switch语句分支选择语句,默认从0依次往上加
{
EXIT,
PLAY
};
int main()
{
int input=0;
char board[2*ROW+1][4*COL+1] = {'\0'}; //将原来的棋盘细化了,为了棋盘更美观
int flag = 1;
int win = 0;
int row,col;
int count = ROW*COL; //一共的棋盘格数,用来判断棋盘是否已满
do
{
menu();
scanf("%d",&input);
switch(input)
{
case PLAY:
{
init_board(board,2*ROW+1,4*COL+1);
while(1)
{
display_board(board,2*ROW+1,4*COL+1);
while(flag)
{
printf("请输入您要落子的坐标(形式为row,col):");
scanf("%d,%d",&row,&col);
if(row-1 >= 0 && row-1<ROW && col-1>=0 && col-1<COL && board[2*row-1][2+4*(col-1)]=='\0')
{
player_move(board,row,col);
--count;
flag = 0;
}
else
{
printf("您输入的坐标有误请重新输入\n");
}
}
if(check_win(board,row-1,col-1))
{
display_board(board,2*ROW+1,4*COL+1);
printf("恭喜您赢得了本局游戏^-^\n");
break;
}else if(count == 0)
{
display_board(board,2*ROW+1,4*COL+1);
printf("该游戏为平局\n");
break;
}
--row,--col;
srand((unsigned)time(NULL));//产生随机值
while(board[2*(row+1)-1][2+4*col] == 'X' || board[2*(row+1)-1][2+4*col] == 'O')
{
//当要落子的位置上为X,或者0,说明该位置已经不空,则重新产生坐标
row = rand()%ROW;
col = rand()%COL;
}
computer_move(board,row,col);
--count; //每落子成功依次,棋盘的空位置减少1
if(check_win(board,row,col))
{
display_board(board,2*ROW+1,4*COL+1);
printf("不好意思,您输给了电脑\n");
break;
}else if(count == 0) //棋盘空位置为0,即已满,还未有赢家出现,此时为平局
{
display_board(board,2*ROW+1,4*COL+1);
printf("该游戏为平局\n");
break;
}
flag = 1;
}
}break;
case EXIT:
{
break;
}
default:
printf("输入有误,请重新输入:");
break;
}
flag = 1;
count = ROW*COL;
}while(input);
return 0;
}