中国象棋棋盘图 画完 但是不知道怎么填充,麻烦了

中国象棋棋子及棋盘的绘制
时间: 23:21:47
&&&& 阅读:509
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&一.题目简介
& 本课程设计主要是使用Swing这个Java自带的图形开发工具实现中国象棋棋子及棋盘的绘制,并根据相应的象棋规则,可以设计棋谱,完成棋谱的保存和对已保存的棋谱的演示,方便现在爱棋人士对残局的收藏于研究,而且达到了进一步巩固课堂上所学到的知识,深刻把握Java语言的重要概念及其面向对象的特性,熟练的应用面向对象的思想和设计方法解决实际问题的能力的目的。
1.当两方有一方将(帅)被吃掉后,程序不能自动结束或提示游戏结束,但想到该程序并不是要进行两方对弈,而是要设计棋谱所以在能力实现范围内可以允许该事件发生;
2.用户不能自动的将棋子删除,使得在摆棋谱过程中增加了工作量,必须从一开始进行,记录每一个棋子的行走过程,因为该程序给用户提供按照一定的思路设计防止其他非专业用户乱走和乱摆。
二.结对分工及过程
承& 担& 的& 任& 务
棋盘界面设计,对弈规则的实现,设计棋谱
保存下棋的步骤从而实现悔棋的实现,完成保存棋谱
1.棋子的设计;
(1)声明一个ChessPiece类,完成各个棋子的外观设计;
public class ChessPiece extends JLabel
&& Color backColor=null,foreC
&& String 颜色类别=
&& ChessBoard board=
int width,
& public ChessPiece(String name,Color fc,Color bc,int width,int height,ChessBoard board){
&&&& this.name=
&&&& this.board=
&&&& this.width=
&&&& this.height=
&&&& foreColor=
&&&& backColor=
&&&& setSize(width,height);
&&&& setBackground(bc);
&&&& addMouseMotionListener(board);
&&&& addMouseListener(board);}
&& public void paint(Graphics g){
&&&& g.setColor(foreColor);
&&&& g.fillOval(2,2,width-2,height-2);
&&&& g.setColor(Color.white);
&&&& g.setFont(new Font("隶书",Font.BOLD,28));&&&
&&&& g.drawString(name,7,height-8);
&&&& g.setColor(Color.yellow);
g.drawOval(2,2,width-2,height-2);}
&& public int getWidth(){}
&& public int getHeight(){}
&& public String getName(){}
&& public Color 获取棋子颜色(){ return foreC}
&& public void set棋子类别(String 类别){颜色类别=类别;}
& public String 棋子类别(){return& 颜色类别;}}
(2)实现各个棋子外观;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ChessBoard extends JPanel implements MouseListener,MouseMotionListener{
public ChessPoint point[][];&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
public int unitWidth,unitH&&&&&&&&&&&&&&&&&&&&&&&&&&&
int x轴长,y轴长;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
int x,y;&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
boolean move=&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
public String&&&& 红方颜色="红色",黑方颜色="黑色";
ChessPiece 红车1,红车2,红马1,红马2,红相1,红相2,红帅,红士1,红士
2,红兵1,红兵2,红兵3,红兵4,红兵5,红炮1,红炮2;
ChessPiece 黑车1,黑车2,黑马1,黑马2,黑将,黑士1,黑士2,黑卒1,黑卒2,黑卒3,黑卒4,黑卒5,黑象1,黑象2,黑炮1,黑炮2;
&& int startX,startY;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&& int startI,startJ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&& public boolean 红方走棋=true,黑方走棋=&&&&&&&&&&&&&&
&& Rule rule=&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&
&& public& MakeChessManual record=&&&&&&&&&&&&&&&&&&&&&&&
&& public& ChessBoard(int w,int h,int r,int c){
&&&&&&& setLayout(null);
&&&&&&& addMouseListener(this);
&&&&&&& addMouseMotionListener(this);
&&&&&&& Color bc=getBackground();
&&&&&&& unitWidth=w;
&&&&&&& unitHeight=h;
&&&&&&& x轴长=r;
&&&&&&& y轴长=c;
&&&&&&& point=new ChessPoint[r+1][c+1];
&&&&&&& for(int i=1;i&=r;i++){
&&&&&&&&&&& for(int j=1;j&=c;j++){
point[i][j]=new ChessPoint(i*unitWidth,j*unitHeight,false); }}
&&&&&&& rule=new Rule(this,point);
&&&&&&& record=new MakeChessManual(this,point) ;&
&&&&&&& 红车1=new ChessPiece("车",Color.red,bc,w-4,h-4,this);
&&&&&&& 红车1.set棋子类别(红方颜色);
&&&&&&& &&//分别是红方各个棋子的设计
&&&&&&& 红兵5=new ChessPiece("兵",Color.red,bc,w-4,h-4,this);
&&&&&&& 红兵5.set棋子类别(红方颜色);
&&&&&&& 黑将=new ChessPiece("将",Color.blue,bc,w-4,h-4,this);
&&&&&&& 黑将.set棋子类别(黑方颜色);
&&&&&&& &&//分别是黑方各个棋子的设计
&&&&&&& 黑卒5=new ChessPiece("卒",Color.blue,bc,w-4,h-4,this);
&&&&&&& 黑卒5.set棋子类别(黑方颜色);
&&&&&&& point[1][10].setPiece(红车1,this);
&&&&&&& &&//红方的每个棋子放到与生活中棋盘位置一样
&&& &&&&point[9][7].setPiece(红兵5,this);
&&&&&&& point[1][1].setPiece(黑车1,this);
&&&//黑方的每个棋子放到与生活中棋盘位置一样
&&&&&&& point[9][4].setPiece(黑卒5,this); }
(3)棋盘的设计:
& public void paintComponent(Graphics g){
&&&& super.paintComponent(g);
&&&&& for(int j=1;j&=y轴长;j++) &&{
g.drawLine(point[1][j].x,point[1][j].y,point[x轴长][j].x,point[x轴长][j].y); }
&&&& for(int i=1;i&=x轴长;i++)&&&& {
&&&&&&&& if(i!=1&&i!=x轴长){
&&&&&&& g.drawLine(point[i][1].x,point[i][1].y,point[i][y轴长-5].x,point[i][y轴长-5].y);
&&&&&& g.drawLine(point[i][y轴长-4].x,point[i][y轴长-4].y,point[i][y轴长].x,point[i][y轴长].y); }
&&&&&&&& else{
&&&&&&& g.drawLine(point[i][1].x,point[i][1].y,point[i][y轴长].x,point[i][y轴长].y);}}&&&&&& g.drawLine(point[4][1].x,point[4][1].y,point[6][3].x,point[6][3].y);
g.drawLine(point[6][1].x,point[6][1].y,point[4][3].x,point[4][3].y);
g.drawLine(point[4][8].x,point[4][8].y,point[6][y轴长].x,point[6][y轴长].y);
g.drawLine(point[4][y轴长].x,point[4][y轴长].y,point[6][8].x,point[6][8].y);
&&&&&& for(int i=1;i&=x轴长;i++){
&&&&&& g.drawString(""+i,i*unitWidth,unitHeight/2);}int j=1;
&&&&& for(char c=‘A‘;c&=‘J‘;c++){
&&&&& g.drawString(""+c,unitWidth/4,j*unitHeight);j++;}}
(4)实现棋子按照生活中的对弈规则走棋的程序如下:
public boolean movePieceRule(ChessPiece piece,int startI,int startJ,int endI,int endJ){
&&& this.piece=this.startI=startI;this.startJ=startJ;
&&& this.endI=endI;
&&& this.endJ=endJ;
&&& int minI=Math.min(startI,endI);
&&& int maxI=Math.max(startI,endI);
&&& int minJ=Math.min(startJ,endJ);
&&& int maxJ=Math.max(startJ,endJ);
boolean 可否走棋=
if(piece.getName().equals("车")){if(startI==endI)
{int j=0;for(j=minJ+1;j&=maxJ-1;j++){
if(point[startI][j].isPiece()){可否走棋=} }
if(j==maxJ){可否走棋=}}
else if(startJ==endJ)& {& int i=0;for(i=minI+1;i&=maxI-1;i++)
{ if(point[i][startJ].isPiece()){可否走棋=
if(i==maxI){可否走棋=}}
else{可否走棋=}}
else if(piece.getName().equals("马"))
&..//以及各个棋子规则的设计
实现棋子按对弈规则的移动并记录棋子移动的位置;
public void mousePressed(MouseEvent e){
&&& ChessPiece piece=Rectangle rect=
&&& if(e.getSource()==this)move=
&&& if(move==false)
&&&&& if(e.getSource() instanceof ChessPiece){
&&&&&&&& piece=(ChessPiece)e.getSource();&&
&&&&&&&& startX=piece.getBounds().x;&&&&&&&
&&&&&&&& startY=piece.getBounds().y;&&&&
&&&&&&&&& rect=piece.getBounds();
&& &&&&&&&for(int i=1;i&=x轴长;i++){
&&&&&&& for(int j=1;j&=y轴长;j++){
&&&&&&& int x=point[i][j].getX();
&&&&&&& int y=point[i][j].getY();
&&&&&&& if(rect.contains(x,y))
&&&&&&& {startI=i;startJ=j;} }}}}
&public void mouseMoved(MouseEvent e){ }
&public void mouseDragged(MouseEvent e){
&&& ChessPiece piece=
&&&&&& if(e.getSource() instanceof ChessPiece){
&&&&&&&&&& piece=(ChessPiece)e.getSource();&& move=
e=SwingUtilities.convertMouseEvent(piece,e,this); }
&&& &&if(e.getSource()==this){if(move&&piece!=null)
&&&&& {x=e.getX(); y=e.getY();
&&&&& if(红方走棋&&((piece.棋子类别()).equals(红方颜色))){
piece.setLocation(x-piece.getWidth()/2,y-piece.getHeight()/2);}
&&&&& if(黑方走棋&&(piece.棋子类别().equals(黑方颜色))){
piece.setLocation(x-piece.getWidth()/2,y-piece.getHeight()/2);}}}}
&public void mouseReleased(MouseEvent e){ &}
public void mouseEntered(MouseEvent e){}
&public void mouseExited(MouseEvent e){}
&public void mouseClicked(MouseEvent e){ }
图中中国象棋是个菜单包括制作棋谱、保存棋谱、演示棋谱三个菜单项
设计actionPerformed事件的代码为:
public void actionPerformed(ActionEvent e){
& if(e.getSource()==制作棋谱) {con.removeAll();
保存棋谱.setEnabled(true);
&&&&&&&& this.setTitle(制作棋谱.getText());
&&&&&&&& board=new ChessBoard(45,45,9,10);
&&&&&&&& record=board.
&&&&&&&& JSplitPane split=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,true,board,record);
&&&&&&&& split.setDividerSize(5);
&&&&&&&& split.setDividerLocation(460);
&&&&&&&& con.add(split,BorderLayout.CENTER);
&&&&&&&& validate();}&&
&&&& if(e.getSource()==保存棋谱) {
&&&&& int state=fileChooser.showSaveDialog(null);
&&&&& File saveFile =fileChooser.getSelectedFile();
if(saveFile!=null&&state==JFileChooser.APPROVE_OPTION)
&&&&& {try{
FileOutputStream outOne=newFileOutputStream(saveFile);
&&&& ObjectOutputStream outTwo=new ObjectOutputStream(outOne);
&&&&& outTwo.writeObject(record.获取棋谱()) ;
&&& &&outOne.close();
&&&&& outTwo.close();}
&catch(IOException event){} }}
&&&& if(e.getSource()==演示棋谱) {&&&&&&&&
&&& con.removeAll();con.repaint();con.validate(); validate();
&&&& 保存棋谱.setEnabled(false);
&&&& int state=fileChooser.showOpenDialog(null);
&&& File openFile =fileChooser.getSelectedFile();
&&&&&&&&& if(openFile!=null&&state==JFileChooser.APPROVE_OPTION)
&{try{FileInputStream inOne=new FileInputStream(openFile);
&& ObjectInputStream inTwo=new ObjectInputStream(inOne);
&&&& 棋谱=(LinkedList)inTwo.readObject() ;
&&&& inOne.close();inTwo.close();ChessBoard board=new ChessBoard(45,45,9,10);demon=new Demon(board);
&&& demon.set棋谱(棋谱);con.add(demon,BorderLayout.CENTER);
con.validate(); validate();
this.setTitle(演示棋谱.getText()+":"+openFile); }
&&&& catch(Exception event)
{JLabel label=new JLabel("不是棋谱文件");
&label.setFont(new Font("隶书",Font.BOLD,60));
label.setForeground(Color.red);
label.setHorizontalAlignment(SwingConstants.CENTER);
con.add(label,BorderLayout.CENTER);
con.validate(); this.setTitle("没有打开棋谱"); validate();} }}else
{JLabel label=new JLabel("没有打开棋谱文件呢");
&&&&&&&&&&&&&&& label.setFont(new Font("隶书",Font.BOLD,50));
&&&&&&&&&&&&&&& label.setForeground(Color.pink);
&&&&&&& label.setHorizontalAlignment(SwingConstants.CENTER);
&&&&&& con.add(label,BorderLayout.CENTER);
&&&&&& con.validate();
&&&&&&& this.setTitle("没有打开棋谱文件呢"); validate();& }}}
三.代码地址
/jixin1995/xiangqi/tree/master
四.测试情况
菜单中保存棋谱:打开保存文件
(1)&&&&&&&&& 打开棋谱
(2)&&&&&&&&& 如果没有选择棋谱文件则会有如下:
(3)&&&&&&&&& 打开棋谱文件后:
五.问题及心得
&&& 采用程序设计棋子与棋盘,使得棋子更加可观,棋子和生活中真实存在的棋子相仿,使得用户使用软件布置棋谱更加习惯,且有悔棋功能方便了用户使用在界面上有用户设计棋谱的步骤使得棋谱从一开始状态到现在状态的过程,满足用户的需要。
&&& 增加打开棋谱文件功能,增加设计棋谱的作用,增加设计过的棋谱的可读性,也可以修改已存的棋谱文件。
&&& 具有演示功能,演示棋局的形成,可以手动一步一步的观察现有棋局的形成,也可以让软件自动形成,还可以设置电脑自动形成的时间间隔,增加与用户之间的互动性,使得软件更加人性化。标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:/jixin-1995/p/4491272.html
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!MFC入门程序训练-------中国象棋游戏程序设计
这个是老板开学前给的第一个MFC编程作业,之前没接触过MFC;所以进入很一段时间的预热期,所谓预热就是做编程前看大量的书。什么WIN32程序原理,消息机制,什么MFC入门啊,总之看了不下10天。边看边编书上的例子程序,我用的教材是图书馆借的丁有和写的一本《VISUAL
C++教程》,这本书不错,当时觉得还是有收获的。但是后面真正编程后发现这段预热期根本没必要那么长...其实当时第一天了解了各感念就行了,就可以真正下手编游戏程序的,算是一个教训。因为真正做的时候又是要重新翻书的,比如起步的绘图就碰到了问题。废话不多说,总结如下:
思路:画棋盘、画棋子、选中棋子、随意移动棋子、走棋规则实现、画选中边框、棋盘响应鼠标移动、写游戏状态、判定将军、判定胜负、游戏声音实现、加AI算法实现人机对弈、实现玩家网上对弈。
&第一次写这样的程序,刚开始除了看书之外不知道如何下手的。因为另一个同学画好了棋盘并实现随意移动棋子,这时我的思路立马就显现在脑海:我把它叫做丁氏填补法——从外壳(界面)一层一层往填充。这个跟以前自顶向下的编程思路有异曲同工之效。
顺着思路,我尽量回忆之间碰到的问题(以后可以边做程序边写BLOG记录的,也算是个教训);首先是version 1:
画棋盘、画棋子、选中棋子、随意移动棋子.说来惭愧,在预热期找到了《visual
c++MFC棋盘类游戏编程实例》的程序实例。其中采用了里面提到的双缓冲绘图方法,其原理是在内存中留块当做是“黑板”吧,然后画好后全面COPY到窗口。
碰到的问题有移动窗口没有重新刷新;这点还是老板回来提醒,说来惭愧。在VIEW类有个OnDraw函数;这个就可以解决了。
在编“选中棋子、随意移动棋子”两个模块中,直接由左键响应函数OnLButtonDown。即发生左键时判定这是第几个点的左键,第一次为选棋子;第二次为移动或者吃。这个有个丁氏填补法的缺点,就是后面深入游戏规则后发现又要重新写原来已编好的程序,笼统的说就是没规划好!这个方法本身的缺点,希望以后用这个方法前整体尽可能详细规划一下。方便未来作业嘛!
走棋规则实现:程序很乱!一直用if_else_if_else总之看这就不是正规军的作品。而这些编写程序上的不规范,也导致了小问题不断,而且改起来很麻烦。添个炮走棋的源代码(这个还是修改过规范过的):
2:&& //& 炮
&&&if( ch.x==x
&& ch.y&y)
&&&&for(int
i=ch.y+1;i&y;i++)
&&&&&if(map[ch.x][i]!=0)
&&&&&&count++;
&&&&if(count==0
&& map[x][y]==0)
&&&&&return
count==1 && ch.color
&& map[x][y]==2) || ( count==1
&& !ch.color
&& map[x][y]==1))
&&&&&return
&&&else if(
ch.x==x &&
&&&&for(int
i=ch.y-1;i&y;i--)
&&&&&if(map[ch.x][i]!=0)
&&&&&&count++;
count==0 && map[x][y]==0)
&&&&&return
count==1 && ch.color
&& map[x][y]==2) || ( count==1
&& !ch.color
&& map[x][y]==1))
&&&&&&return
&&&&&return
&&&else if(
ch.y==y &&
&&&&for(int
i=ch.x+1;i&x;i++)
&&&&&if(map[i][ch.y]!=0)
&&&&&&count++;
&&&&if(count==0
&& map[x][y]==0)
&&&&&return
count==1 && ch.color
&& map[x][y]==2) || ( count==1
&& !ch.color
&& map[x][y]==1))
&&&&&&return
&&&&&return
&&&else if(
ch.y==y &&
&&&&for(int
i=ch.x-1;i&x;i--)
&&&&&if(map[i][ch.y]!=0)
&&&&&&count++;
&&&&if(count==0
&& map[x][y]==0)
&&&&&return
count==1 && ch.color
&& map[x][y]==2) || ( count==1
&& !ch.color
&& map[x][y]==1))
&&&&&&return
&&&&&return
&&&&return
棋盘响应鼠标移动、写游戏状态、判定将军、判定胜负基本上没碰到大的问题;游戏声音的实现上倒是碰到了,具体解决之前提过:
关于后面的“加AI算法实现人机对弈、实现玩家网上对弈”,因为时间的原因放到了现在还是没有完成。想得是以后碰到类似的知识再“丁氏填补”进去!不断完善这个象棋程序。才接到新任务,关于Socket编程的实验指导编写,我想完成后对“实现玩家网上对弈”会有所帮助...期待ING
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 象棋棋盘 的文章

 

随机推荐