天天看點

結對項目—五子棋

 五子棋Github托管位址:

 https://github.com/sunyuanyuan/test/blob/master/Game

分工:

負責寫代碼:趙存存

負責調試程式:孫媛媛

一、實踐目的

1.掌握Java常用基礎類API。

2.掌握輸入輸出流常用類API。

3.掌握Java異常處理。

二、實踐要求

利用Java常用基礎類API、輸入輸出流常用類API、Java異常處理等完成所選項目的程式設計。

三、項目需求

所選項目名稱:五子棋遊戲

現在各大軟體公司都有自己的、各種的程式,但是這些公司都有自己的版權,我們也不可能得到這些源代碼!而且這些公司的程式也相當複雜,僅從日常應用方面來說,對于初學java的我們也無法了解,就需要我們開發一個簡單易懂的五子棋遊戲程式。

四、核心算法詳細設計     

本程式實作的是一單機雙人對戰五子棋遊戲

本程式由五個java源程式檔案組成,Game.java、GameFrame.java、GamePanel.java、 ChessMan.java、Player.java

Game.java

import javax.swing.*;

public class Game {

public static void main(String[] args) {

GameFrame GFrame=new GameFrame();

GFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

GFrame.setVisible(true);

}

GameFrame.java

import java.awt.*;

class GameFrame extends JFrame {

private static final int Width=570;

private static final int Height=470;

GameFrame(){

setTitle("五子棋遊戲");

CenteredFrame();

setSize(Width,Height); 

GamePanel Gpanel=new GamePanel();

add(Gpanel); 

void CenteredFrame(){

Toolkit kit=Toolkit.getDefaultToolkit();

Dimension screenSize=kit.getScreenSize();

int screenHeight=screenSize.height;

int screenWidth=screenSize.width;

int Xposition=(screenWidth-Width)/2;

int Yposition=(screenHeight-Height)/2;

setLocation(Xposition,Yposition);

GamePanel.java

import java.awt.event.*;

class GamePanel extends JPanel {

private Point cursor=new Point(40,60); //棋盤坐标

private int[][] ChessState=new int[18][18];//棋盤狀态 

private int i=0;//橫坐标   

private int j=0;//縱坐标

private final static int testnum=5;//五子棋的規定棋子數

private Player Black=new Player(1,Color.BLACK,"黑方");//黑方棋子

private Player White=new Player(2,Color.WHITE,"白方");//白方棋子

private Player Cplayer=null;//目前使用者的引用

private JTextField textBlack=new JTextField("",5);//黑方文本提示框對象和文本長度設定

private JTextField textWhite=new JTextField("",5);//白方文本提示框對象和文本長度設定

private String Nothing="";

private String textblack="請黑方下子";//黑方提示文本

private String textwhite="請白方下子";//白方提示文本

GamePanel(){

setLayout(null);

Initialization();

setFocusable(true);

JButton Rutton=new JButton("重新開局");

Rutton.setBounds(20,14,100,26);

RestartListener restart=new RestartListener();

Rutton.addActionListener(restart);

add(Rutton);

textBlack.setHorizontalAlignment(JTextField.CENTER);

textBlack.setBounds(150,14,110,26);

textBlack.setEditable(false);

add(textBlack);

textWhite.setHorizontalAlignment(JTextField.CENTER);+ textWhite.setBounds(290,14,110,26);

textWhite.setEditable(false);

add(textWhite);

JTextArea gInstruction=new JTextArea();

gInstruction.setSelectedTextColor(new Color(238,238,238));

String gSInstruction=

"Play1(黑方) Key \nup--------W \ndown----S \nleft--------A \nright------F \n\n"+

"Play2(白方) Key \nup--------up \ndown----down \nleft--------left \nright------right \n\n"+

"Exit game: \nPress Esc";

gInstruction.setText(gSInstruction);

gInstruction.setEditable(false);

gInstruction.setBounds(440,60,100,340);

add(gInstruction);

ChessManPerformListener Perform=new ChessManPerformListener();

addKeyListener(Perform);

// 設定第一個JTextField輸出"請黑方下棋",坐标為(40,60)

void Initialization(){ 

for(int i=0,j;i<18;i++)

for(j=0;j<18;j++){

ChessState[i][j]=0; 

cursor.setLocation(40,60);

Cplayer=Black;

textBlack.setText(textblack);

textWhite.setText(Nothing);

//畫棋盤和初始化棋局狀态

protected void paintComponent(Graphics g){

super.paintComponent(g);

Graphics2D g2=(Graphics2D) g;

for(int i=60;i<=400;i+=20){

g2.drawLine(40,i,380,i);

for(int j=40;j<=380;j+=20){

g2.drawLine(j,60,j,400);

g2.drawString("_",cursor.x-6,cursor.y);

g2.drawString("_",cursor.x,cursor.y);

for(i=0;i<18;i++)

if(ChessState[i][j]!=0){

if(ChessState[i][j]==1){

g2.setPaint(Black.getplayerChessManColor()); 

if(ChessState[i][j]==2){

g2.setPaint(White.getplayerChessManColor());

g2.fillOval(j*20+40-10, i*20+60-10, ChessMan.getChessManSize(), ChessMan.getChessManSize());

//判斷棋盤的目前位置是否已有棋子

boolean isChessState(){ 

this.j=(cursor.x-40)/20;

this.i=(cursor.y-60)/20;

if(ChessState[this.i][this.j]!=0)

return true;

else

return false; 

//記錄落子後棋盤的目前位置的狀态

void RecordChessState(){

ChessState[this.i][this.j]=Cplayer.getCurrentIdentify();

//判斷目前玩家落子後是否赢了

void JudgeWin(){

for(int i=0;i<4;i++)

if(JudgeWinLine(i)){

//提示目前玩家已經獲得勝利

try{

String Ginformation="GameInformation";

String Message="恭喜玩家"+Cplayer.getsIdentify()+"獲勝!"+"\n"+"繼續遊戲還是退出遊戲?";

String[] options = {"繼續","退出"};

int selection=JOptionPane.showOptionDialog(null,Message,Ginformation,

JOptionPane.YES_NO_OPTION,JOptionPane.INFORMATION_MESSAGE ,null,options,options[0]);//throws HeadlessException

if(selection==JOptionPane.OK_OPTION){ 

repaint();

return;

if(selection==JOptionPane.NO_OPTION){

System.exit(0);//退出程式

}catch(HeadlessException e){

e.printStackTrace();

//如果目前方沒有赢棋則雙方輪換

ChangeCurrentPlayer();

//在目前方向上是否有連續的五隻棋子

boolean JudgeWinLine(int direction){

int i,j,di,dj,count;

i=j=di=dj=count=0;

switch(direction){

case 0:

j=this.j-(testnum-1);

i=this.i;

dj=1;

di=0;

break;

case 1:

j=this.j;

i=this.i-(testnum-1);

dj=0;

di=1;

case 2:

i=this.i+(testnum-1);

di=-1;

case 3:

for(int k=0;k<testnum*2+1;k++){

if(j>=0&&j<18&&i>=0&&i<18){

if(ChessState[i][j]==Cplayer.getCurrentIdentify()){

count++;

if(count>=testnum)

count=0;

j+=dj;

i+=di;

return false;

//更換目前玩家

void ChangeCurrentPlayer(){

if(Cplayer==Black){

Cplayer=White;

textBlack.setText(Nothing);

textWhite.setText(textwhite);

else{

//重新開局監聽器

private class RestartListener implements ActionListener{

public void actionPerformed(ActionEvent arg0) {

requestFocus();

//棋盤、棋局狀态監聽器

private class ChessManPerformListener implements KeyListener{

//玩家2的按鍵

public void keyPressed(KeyEvent event) {

int keyCode=event.getKeyCode();

if(keyCode==KeyEvent.VK_ESCAPE)

System.exit(0);

if(Cplayer.getCurrentIdentify()==2){//判别目前玩家

if(keyCode==KeyEvent.VK_LEFT){

if(cursor.x>40)

cursor.x-=20;

else if(keyCode==KeyEvent.VK_RIGHT){

if(cursor.x<380)

cursor.x+=20;

else if(keyCode==KeyEvent.VK_UP){

if(cursor.y>60)

cursor.y-=20;

else if(keyCode==KeyEvent.VK_DOWN){

if(cursor.y<400)

cursor.y+=20;

else if(keyCode==KeyEvent.VK_ENTER){

if(!isChessState()){

Cplayer.PerformChessMan();

RecordChessState();

JudgeWin();//判定目前落子後是否赢棋

repaint(); 

public void keyReleased(KeyEvent event) {}

//玩家1的按鍵

public void keyTyped(KeyEvent event) {

char keyChar=event.getKeyChar();

if(Cplayer.getCurrentIdentify()==1){//判别目前玩家

if(keyChar=='a'){

if(cursor.x>40)//對移動光标超界現象做判别

else if(keyChar=='d'){

if(cursor.x<380) 

else if(keyChar=='w'){

else if(keyChar=='s'){

else if(keyChar==' '){

if(!isChessState()){ //落子前先判斷目前位置上是否已有棋子

Cplayer.PerformChessMan();//落子 

RecordChessState();//記錄目前落子後棋盤狀态

ChessMan.java

import java.awt.Color;

class ChessMan {

private static final int ChessManSize=20;

private Color ChessManColor;

ChessMan(Color c){

ChessManColor=c;

static int getChessManSize(){

return ChessManSize;

Color getChessManColor(){

return ChessManColor;

Player.java 

class Player {

private int identify;

private ChessMan pChessMan;

private String PlayerStringIdentify;

Player(int identify,Color c,String sIdentify){

this.identify=identify;

pChessMan=new ChessMan(c);

this.PlayerStringIdentify=sIdentify;

int getCurrentIdentify(){

return identify;

String getsIdentify(){

return PlayerStringIdentify;

void PerformChessMan(){}

Color getplayerChessManColor(){

return pChessMan.getChessManColor();

五、程式運作結果

結對項目—五子棋
結對項目—五子棋

六 、心得體會

過這次的結對實驗,我從書本上學習到的理論知識用到了實踐上,進而進一步鞏固和豐富了我所學過的知識,讓我更深層次地認識到Java及其強大的功能。同時,做這門課程設計也進一步加強了我的動手能力與合作能力。

趙存存代碼寫的很清楚,我們交流的非常愉快。

附上一張我們一起做代碼的照片

結對項目—五子棋
下一篇: 結對作業