写在前面的话:“ 你现在的状态,是过去的你用努力换来的,而你未来的状态,是现在的你用努力决定的。”
九月你好,还未还得及感受,你就要离去。以前总是担心着未来的未发生的事情,前几天听完bilibi架构师学长对我问题的回答后。有所感触。我想,现在的我,规划好以后要做的事情,把目前手里的事情做好,不好高骛远,脚踏实地,充实自己,机会是留给有准备的人的。我是梦阳辰,快和我一起加油吧!
1.设计棋盘类用来构建棋盘。
2.设计棋局类,用来保存棋局情况(用二维数组存储)。
3.设计物理地址类用来表示物理地址。
4.设计逻辑地址类用来表示棋盘上逻辑坐标。
5.系统游戏类,也为主类。用来绘制棋盘,绘制棋子,并对用户单击鼠标(下棋)进行响应(做相应的处理)。
6.因为监听鼠标单击一直在进行,所以游戏可以一直运行,知道用户主动退出游戏。
判断输赢的核心算法:
/**S
* 判断棋局是否获胜(落点位置周围是否有5个相同颜色的棋子
* @return -1黑色方赢 0平局 1白色方赢
*/
public int isWin(CoordinateLogical c){
int color = situation[c.getRow()][c.getCol()];//当前棋子的颜色
//垂直方向
if((extend(c,0)+extend(c,4))>=4) {
return color;
}
//副对角线方向
if((extend(c,1)+extend(c,5))>=4) {
return color;
}
//水平方向
if((extend(c,2)+extend(c,6))>=4) {
return color;
}
//主对角线方向
if((extend(c,3)+extend(c,7))>=4) {
return color;
}
return 0;
}
/**
* 从指定位置往某个方向扩展
* @parm c 位置
* @param direction 0 向上 1 右上 2右 3右下 4向下 5左下 6左 7左上
* @return 可扩展的同颜色棋子的个数
*/
private int extend (CoordinateLogical c ,int direction){
int count = 0;
int row = c.getRow();
int col = c.getCol();
int color = situation[c.getRow()][c.getCol()];//当前棋子的颜色
//一个方向最多需要判断4个即可
for(int i=0;i<4;i++){
switch (direction){
case 0: row--;break;
case 1:row--;col++;break;
case 2:col++;break;
case 3:row++;col++;break;
case 4:row++;break;
case 5:row++;col--;break;
case 6:col--;break;
case 7:row--;col--;break;
}
if(row<0||row>=Chessboard.getRows()||col<0||col>=Chessboard.getCols()){
break;
}
if(situation[row][col]==color){
count++;
} else {
break;
}
}
return count;
}
通过判断当前所下棋子是否与周围(米字方向)同色棋子组成五连珠。
1.属性situation:用二维数组存储棋局每个点位的情况。
2.棋子属性:定义黑棋(black),白棋的属性(white)。
3.先手属性:定义当前移动方(mover)。
1.判断逻辑地址是否存在棋子(exist)
2.落子(add)
3.判断棋局是否获胜(isWin)
package GoBang_Game;
//棋局类
public class ChessSituation {
public final static int BLACK = -1;//黑色棋子
public final static int NONE = 0;//无棋子
public final static int WHITE = 1;//白色棋子
private int[][] situation;//棋局所有落点的情况
private int mover;//表示当前谁落子,1为白子,-1为黑子
/**
* 确定落点
* 构造函数
*/
public ChessSituation(int rows,int cols) {
situation = new int[rows][cols];//默认值为0
mover = BLACK;//黑方先动
}
/**
* 判断逻辑地址是否存在棋子
* @return true or false
*/
public boolean exist(CoordinateLogical c){
return situation[c.getRow()][c.getCol()]!=ChessSituation.NONE;
}
/**
* 落子
* @param c 落子的位置
* @return 落子的颜色
*/
public int add(CoordinateLogical c){
int color = mover;
situation[c.getRow()][c.getCol()] = color;//存储了颜色,也就代表了哪一方
mover = -mover;//切换谁下棋
return color;
}
/**S
* 判断棋局是否获胜(落点位置周围是否有5个相同颜色的棋子
* @return -1黑色方赢 0平局 1白色方赢
*/
public int isWin(CoordinateLogical c){
int color = situation[c.getRow()][c.getCol()];//当前棋子的颜色
//垂直方向
if((extend(c,0)+extend(c,4))>=4) {
return color;
}
//副对角线方向
if((extend(c,1)+extend(c,5))>=4) {
return color;
}
//水平方向
if((extend(c,2)+extend(c,6))>=4) {
return color;
}
//主对角线方向
if((extend(c,3)+extend(c,7))>=4) {
return color;
}
return 0;
}
/**
* 从指定位置往某个方向扩展
* @parm c 位置
* @param direction 0 向上 1 右上 2右 3右下 4向下 5左下 6左 7左上
* @return 可扩展的同颜色棋子的个数
*/
private int extend (CoordinateLogical c ,int direction){
int count = 0;
int row = c.getRow();
int col = c.getCol();
int color = situation[c.getRow()][c.getCol()];//当前棋子的颜色
//一个方向最多需要判断4个即可
for(int i=0;i<4;i++){
switch (direction){
case 0: row--;break;
case 1:row--;col++;break;
case 2:col++;break;
case 3:row++;col++;break;
case 4:row++;break;
case 5:row++;col--;break;
case 6:col--;break;
case 7:row--;col--;break;
}
if(row<0||row>=Chessboard.getRows()||col<0||col>=Chessboard.getCols()){
break;
}
if(situation[row][col]==color){
count++;
} else {
break;
}
}
return count;
}
public int[][] getSituation() {
return situation;
}
public void setSituation(int[][] situation) {
this.situation = situation;
}
public int getMover() {
return mover;
}
public void setMover(int mover) {
this.mover = mover;
}
}
1.行数(rows)
2.列数(cols)
3.间距(size)
4.棋盘的位置(margin)
1.初始化棋盘(init)
2.将物理地址转换为逻辑坐标(convert)。
注意:将物理地址转换成逻辑坐标时:
横坐标转化成列号。
纵坐标转换成行号。
3.将逻辑坐标转换成物理地址(convert)。
目的是为了在物理地址画棋子。
package GoBang_Game;
//棋盘类
public class Chessboard {
private static int rows;//行数
private static int cols;//列数
private static int size;//间距
private static int margin;//棋盘的位置
/**
* 初始化
* @param n1 行数
* @param n2 列数
* @param n3 间距
* @param n4 外边距
*/
public static void init(int n1, int n2,int n3, int n4) {
rows = n1;
cols = n2;
size = n3;
margin = n4;
}
/**
* 将物理地址装换成逻辑坐标
* @param c 物理坐标
* @return 逻辑坐标
*/
public static CoordinateLogical convert(CoordinatePhysical c){
CoordinateLogical c1 = new CoordinateLogical();
c1.setCol(Math.round((float)(c.getX()-margin)/size));//行号
c1.setRow(Math.round((float)(c.getY()-margin)/size));//列号
return c1;
}
/**
* 将逻辑坐标装换成物理地址
* @param c 逻辑坐标
* @return 物理坐标
*/
public static CoordinatePhysical convert(CoordinateLogical c){//便于画棋子
CoordinatePhysical c1 = new CoordinatePhysical();
c1.setX(c.getCol()*size+margin);//横坐标
c1.setY(c.getRow()*size+margin);//纵坐标
return c1;
}
public static int getRows() {
return rows;
}
public static void setRows(int rows) {
Chessboard.rows = rows;
}
public static int getCols() {
return cols;
}
public static void setCols(int cols) {
Chessboard.cols = cols;
}
public static int getSize() {
return size;
}
public static void setSize(int size) {
Chessboard.size = size;
}
public static int getMargin() {
return margin;
}
public static void setMargin(int margin) {
Chessboard.margin = margin;
}
public static int getWidth() {
return (margin*2+size*(cols-1));
}
public static int getHight() {
return (margin*2+size*(rows-1));
}
}
1.横坐标(x)
2.纵坐标(y)
package GoBang_Game;
public class CoordinatePhysical {
private int x;//横坐标
private int y;//纵坐标
public CoordinatePhysical() {
}
public CoordinatePhysical(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
1.行号(row)
2.列号(col)
package GoBang_Game;
public class CoordinateLogical {
private int row;//行号
private int col;//列号
public CoordinateLogical() {
}
public CoordinateLogical(int row, int col) {
this.row = row;
this.col = col;
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getCol() {
return col;
}
public void setCol(int col) {
this.col = col;
}
}
1.窗体
2.画布
3.绘图对象
4.按钮
5.棋局属性
1.主方法:(main)
创建游戏对象
2.构造方法:(Game)
创建窗口,画布,增加按钮,响应按钮,并响应鼠标做对应处理。
3.绘制棋盘(drawBoard)
4.绘制棋子(drawChess)
5.处理鼠标单击(下棋)
package GoBang_Game;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class Game {
private static Frame frame;//窗体
private static Canvas canvas;//画布
private Graphics graphics;//绘图对象
private Button button;//按钮
private ChessSituation chessSituation;//棋局
public static void main(String[] args) {
Game game = new Game(15,15,50,50);
}
public Game(int rows, int cols, int size , int margin){
Chessboard.init(rows,cols,size,margin);
chessSituation = new ChessSituation(rows,cols);
//初始化窗口
int width = Chessboard.getWidth();
int height = Chessboard.getHight()+100;
frame = new Frame("五子棋-梦阳辰");
frame.setSize(width,height);
frame.setLayout(new FlowLayout());
frame.setVisible(true);//显示窗体
//准备画布
canvas = new Canvas();
canvas.setSize(width,height);//指定尺寸
frame.add(canvas);
//画布单击响应
canvas.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
CoordinatePhysical c = new CoordinatePhysical(e.getX(),e.getY());
int a =handle(c);
if(a==1){
JOptionPane.showMessageDialog(null, "白色方赢了", "游戏结束",JOptionPane.INFORMATION_MESSAGE);
drawBoard();//重新绘制棋盘
chessSituation.setSituation(new int [Chessboard.getRows()][Chessboard.getCols()]);//将棋局情况 清0
chessSituation.setMover(chessSituation.BLACK);//设置黑色方为先手
}
else if(a==-1){
JOptionPane.showMessageDialog(null, "黑色方赢了", "游戏结束",JOptionPane.INFORMATION_MESSAGE);
drawBoard();//重新绘制棋盘
chessSituation.setSituation(new int [Chessboard.getRows()][Chessboard.getCols()]);//将棋局情况 清0
chessSituation.setMover(chessSituation.BLACK);//设置黑色方为先手
}
super.mouseClicked(e);
}
});
//增加按钮
button = new Button("Start Game");
button.setSize(130,80);
frame.add(button);
//响应按钮
button.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent mouseEvent) {
graphics = canvas.getGraphics();
drawBoard();//绘制棋盘
chessSituation.setSituation(new int [Chessboard.getRows()][Chessboard.getCols()]);//将棋局情况 清0
chessSituation.setMover(chessSituation.BLACK);//设置黑色方为先手
super.mouseClicked(mouseEvent);
}
});
//增加按钮
button = new Button("Exit Game");
button.setSize(130,80);
frame.add(button);
//响应按钮
button.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent mouseEvent) {
graphics = canvas.getGraphics();
frame.setVisible(false);//退出窗体
System.exit(0);//退出程序
super.mouseClicked(mouseEvent);
}
});
}
/**
* 绘制棋盘
*/
public void drawBoard(){
graphics.setColor(Color.YELLOW);
graphics.fillRect(0,0,Chessboard.getWidth(),Chessboard.getHight());
graphics.setColor(Color.BLACK);
//绘制纬线
int x1 = Chessboard.getMargin();
int y1 = Chessboard.getMargin();
int x2 = x1+(Chessboard.getSize()*(Chessboard.getCols()-1));
int y2 = y1;
for(int i=0;i<Chessboard.getRows();i++){
graphics.drawLine(x1,y1,x2,y2);
y1 += Chessboard.getSize();
y2 += Chessboard.getSize();
}
//绘制纬线
x1 = Chessboard.getMargin();
y1 = Chessboard.getMargin();
x2 = x1;
y2 = y1+(Chessboard.getSize()*(Chessboard.getRows()-1));
for(int i=0;i<Chessboard.getCols();i++){
graphics.drawLine(x1,y1,x2,y2);
x1 += Chessboard.getSize();
x2 += Chessboard.getSize();
}
}
/**
* 绘制棋子
* @param c
* @param color 颜色(1黑色,-1白色)
*/
public void drawChess(CoordinateLogical c, int color){
int r = (int) (Chessboard.getSize()*0.4);
CoordinatePhysical c1= Chessboard.convert(c);//得到物理坐标
//计算外切正方形的起点和宽高
int x = c1.getX() -r ;
int y = c1.getY() -r ;
int width = 2*r;
int heigth = 2*r;
graphics.setColor(color==chessSituation.BLACK?Color.BLACK:Color.WHITE);
graphics.fillArc(x,y,width,heigth,0,360);
}
/**
* 用户在棋盘上单击之后的处理
* @param c 单击的位置
* @return 输赢结果
*/
public int handle(CoordinatePhysical c) {
CoordinateLogical c1 = Chessboard.convert(c);
if(!chessSituation.exist(c1)){
//落子
int color = chessSituation.add(c1);
//绘制棋子
drawChess(c1,color);
//返回落子后的输赢
return chessSituation.isWin(c1,color);
}
return chessSituation.NONE;
}
}
关注公众号【轻松玩编程】回复关键字激活码即可获取:全家桶通用激活码(激活码支持idea,pycharm,webstorm,phpstorm…激活)定期更新。适用于最新及以下版本。(无需破解和修改hosts,如果破解过请卸载重新安装官方原版,如果修改过hosts,请删除你添加的网址,然后重新激活)
回复关键字“电子书”,“计算机资源”,“Java从入门到进阶”,”JavaScript教程“,“算法”,“Python学习资源”,“人工智能”等即可获取学习资源。
喜欢就争取,得到就珍惜,生活就是这样,脚长在自己身上,往前走就对了,直到向往的风景,变成走过的地方。