(游戏:四子连 )四子连是一个两个人玩的棋盘游戏,在游戏中,玩家轮流将有颜色的棋子放在一个六行七列的垂直悬挂的网格中:
这个游戏的目的是在对手实现一行、一列或者一条对角线上有四个相同颜色的棋子之前,你能先做到。程序提示两个玩家交替的下红子Red或黄子Yellow。当放下一子时,程序在控制台重新显示这个棋盘,然后确定游戏状态(赢、平局还是继续),下面是一个运行示例:
。。。
。。。
。。。
-----此题源自《java语言程序设计》习题8.20
目录
对象分析:
属性:棋盘:Graph、top——二维字符(串)组模拟栈组;
棋子:C(颜色)——奇偶交替变换
棋盘剩余空格:empty——用于判断平局
方法:下棋:input()——修改二维组
判断输赢:judge()——判断胜出
显示棋盘:show()——展示棋盘
胜出条件:四子连珠
代码思路:每次下棋之后都要进行判断,是否有人胜出,怎么判断呢?可以在下棋之后,以此棋为中心,向四个方向(水平,垂直,两条对角线:通过坐标的加减)判断是否出现了四子连珠(注意边界,易出现bug),具体实现,请看代码。
当然也可以在整个棋盘搜索,代码容易写,但降低了效率。
注意:边界要判断仔细
双向检测连珠,有可能你最后一次是下3个棋子中间胜出
Java(最终代码):
java作业,可参考,别抄.
judge(递归实现):单向探测求和,(也可双向,但效率没提高多少,且可读性不高)
import java.util.Scanner;
public class JavaGame {
int row,column; //行列
char Graph[][]; //二维棋盘
int top[]; //模拟栈尾指针
String C[]={"red","yellow"}; //棋子颜色
int empty; //棋盘剩余空格
public JavaGame(int r,int c){ //初始化棋盘数据
empty=r*c;
row=r;column=c;
Graph=new char[r][c];
top=new int[c];
for(int i=0;i<c;i++) //初始化数组栈
top[i]=-1;
for(int i=0;i<r;i++)
for(int j=0;j<c;j++)
Graph[i][j]=' ';
}
public void show(){ //展示棋盘
for(int i=row-1;i>=0;i--){
System.out.print("|");
for(int j=0;j<column;j++)
System.out.print(Graph[i][j]+"|");
System.out.println();
}
}
public int Input(int y,int key){ //下棋
if(y>=column||y<0||top[y]==row-1){
System.out.println("out of range");
return 1;
}
Graph[++top[y]][y]=C[key%2].toUpperCase().charAt(0);
empty--;
return 0;
}
public int judge(int x,int y) { //判断是否有人胜出
if (search(Graph[x][y], x, y, 1, 0) + search(Graph[x][y], x, y, -1, 0) == 3|| //水平探测
search(Graph[x][y], x, y, 1, 1) + search(Graph[x][y], x, y, -1, -1) == 3|| //对角探测
search(Graph[x][y], x, y, 0, 1) + search(Graph[x][y], x, y, 0, -1) == 3|| //垂直探测
search(Graph[x][y], x, y, 1, -1) + search(Graph[x][y], x, y, -1, 1) == 3) //对角探测
return 1;
return 0; //未有人获胜
}
public int search(char k, int a, int b, int z, int f) { //单向探测函数
a += z; b += f;
if (b >= column || a >= row || a < 0 || b < 0||Graph[a][b] != k)
return 0;
return search(k, a , b , z, f)+1;
}
public static void main(String[] args) {
JavaGame My=new JavaGame(6,7);
Scanner input=new Scanner(System.in);
int tmp,key;
My.show();
for(int i=0;;){
System.out.print("Drop a "+My.C[i%2]+" disk at column(0-6) : ");
tmp=input.nextInt();
if(My.Input(tmp,i)!=0) //出错后 执行下一循环(i没有++)
continue;
My.show();
if(My.judge(My.top[tmp],tmp)==1){ //判断是否有人胜出
System.out.println("The "+My.C[i%2]+" player won");
break;
}
if(My.empty==0){ //平局
System.out.println("Chess draw");
break;
}
i++;
}
}
}
C++(第1版,有点乱):
judge:非递归(java也可用):双向探测
#include<iostream>
#include<string>
using namespace std;
class Chess {
public:
Chess(); //初始化成员数据
void show(); //显示棋盘
int input(int y,int key); //下棋
int judge(int y); //判断结果
string C[2] = { "red","yellow" };
private:
string Graph[6][7];
int top[7]; //模拟栈
};
Chess::Chess(){
memset(top, -1, sizeof(top)); //数组top初始化为-1
for (int i = 0; i < 6; i++) { //初始化Graph
for (int j = 0; j < 7; j++) {
Graph[i][j] = " ";
}
}
}
void Chess::show(){
for (int i = 5; i >= 0; i--) {
cout << "|";
for (int j = 0; j < 7; j++)
cout << Graph[i][j] << "|";
cout << endl;
}
}
int Chess::input(int y,int key) {
if (y > 6 || y < 0){ //越界检测
cout << "y is out of range[0,6]" << endl;
return 1;
}
if (top[y] == 5) {
cout << "x is out of range" << endl;
return 1;
}
Graph[++top[y]][y] = toupper(C[key % 2][0]); //赋值操作
return 0;
}
int Chess::judge(int y) {
int kx[4] = { 0, 1, 1, 1 }, //八个方向(4个正方向,另外4个负方向取反)
ky[4] = { 1, 1, 0,-1 };
int a, b, count = 0;
int x = top[y];
for (int i = 0; i < 4; i++) { //八个方向检测
a = x; //数据初始化
b = y;
count = 0;
for (int j = 0; j < 3; j++) { //检测四个正方向
a += kx[i];
b += ky[i];
if (b > 6 || a > 5 || a < 0 || b < 0 || Graph[a][b] == " ") //边界检测
break;
if (Graph[a][b] == Graph[x][y] )
count++;
}
a = x;
b = y;
for (int j = 0; j < 3; j++) { //检测四个负方向
a -= kx[i];
b -= ky[i];
if (b > 6 || a > 5 || a < 0 || b < 0 || Graph[a][b] == " ") //边界检测
break;
if (Graph[a][b] == Graph[x][y]) //逻辑判断
count++;
}
if (count == 3) //四子相连,此人胜出
return 1;
}
for (int i = 0; i < 7; i++) { //只要有一列未满,返回0
if (top[i] != 5)
return 0;
}
return -1; //全满,返回-1(平局)
}
int main() {
Chess myChess;
myChess.show();
int tmp,key;
for (int i = 0;;) { //i奇偶决定颜色
cout << "Drop a "<< myChess.C[i % 2] <<" disk at column(0-6): ";
cin >> tmp;
if (myChess.input(tmp, i)) //bug检测
continue;
system("cls"); //清屏
myChess.show();
key = myChess.judge(tmp); //key判断输赢,平局
if (key==1) {
cout << "The " << myChess.C[i % 2] << " player won" << endl;
break;
}
else if (key == -1) {
cout << "Chess draw" << endl;
break;
}
i++;
}
return 0;
}