• JAVA 8.20 游戏:四子连(Java&C++)


    (游戏:四子连 )四子连是一个两个人玩的棋盘游戏,在游戏中,玩家轮流将有颜色的棋子放在一个六行七列的垂直悬挂的网格中:

            这个游戏的目的是在对手实现一行、一列或者一条对角线上有四个相同颜色的棋子之前,你能先做到。程序提示两个玩家交替的下红子Red或黄子Yellow。当放下一子时,程序在控制台重新显示这个棋盘,然后确定游戏状态(赢、平局还是继续),下面是一个运行示例:

     

    。。。

    。。。

    。。。

                                                                                                                -----此题源自《java语言程序设计》习题8.20

    目录

    对象分析:

    胜出条件:四子连珠

    Java(最终代码):

    C++(第1版,有点乱):

     


    对象分析:

            属性:棋盘: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;
    }

     

  • 相关阅读:
    Shell脚本
    StateListDrawable、ColorStateList
    android 继承viewgroup的类不调用onDraw
    默默的向3位大牛学习.....
    总结的一些android公共库,包含公共的View、缓存以及一些工具类
    android屏幕 单位转换
    android 实现自动滚动的 Banner 横幅
    C# 求最大相同子字符串
    C# 把数字转换成链表
    C# 求奇数和偶数和
  • 原文地址:https://www.cnblogs.com/F-itachi/p/9974349.html
Copyright © 2020-2023  润新知