import java.util.Random;
public class Game {
public static void main(String[] args) {
System.out.println("比赛开始");
Person p1 = new Person("刘邦", 100, 10);
Random random = new Random();
} else {
}
p1.printState();
System.out.println("game over!");
class Person {
private int blood;// 初始血量
private int range;// 掉血范围
private String name;// 姓名
public String getName() {
return name;
public void setName(String name) {
this.name = name;
public int getRange() {
return range;
public void setRange(int range) {
this.range = range;
public int getBlood() {
return blood;
public void setBlood(int blood) {
this.blood = blood;
// 构造函数
public Person(String name, int blood, int range) {
// 击打
public void beat(Person person) {
int bleeding = person.hurt();
System.out
.println(String.format("%s打了%s一耳光,%s流了%s滴血.", this.name, person.getName(), person.getName(), bleeding));
// 被打,受伤
public int hurt() {
int bleeding = random.nextInt(this.range) + 1;
if (bleeding this.blood) {
bleeding = this.blood;
this.blood -= bleeding;
return bleeding;
// 输出状态
public void printState() {
if (this.blood == 0) {
System.out.println(String.format("%s被打死了", this.name));
System.out.println(String.format("%s还剩%s滴血", this.name, this.blood));
结果(随机):
比赛开始
刘邦打了项羽一耳光,项羽流了1滴血.
项羽打了刘邦一耳光,刘邦流了10滴血.
刘邦打了项羽一耳光,项羽流了10滴血.
刘邦被打死了
game over!
全手写,望采纳,谢谢!
人机的没有,不过自己打自己的有.
------------------------------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class mypanel extends Panel implements MouseListener
{
int chess[][] = new int[11][11];
boolean Is_Black_True;
mypanel()
Is_Black_True = true;
for(int i = 0;i 11;i++)
for(int j = 0;j 11;j++)
chess[i][j] = 0;
addMouseListener(this);
setBackground(Color.BLUE);
setVisible(true);
public void mousePressed(MouseEvent e)
int x = e.getX();
int y = e.getY();
return;
if(Is_Black_True == true)
Is_Black_True = false;
repaint();
Justisewiner();
if(Is_Black_True == false)
void Drawline(Graphics g)
g.setColor(Color.WHITE);
void Drawchess(Graphics g)
if(chess[i][j] == 1)
g.setColor(Color.BLACK);
void Justisewiner()
int black_count = 0;
int white_count = 0;
int i = 0;
for(i = 0;i 11;i++)//横向判断
black_count++;
JOptionPane.showMessageDialog(this, "黑棋胜利");
Clear_Chess();
else
black_count = 0;
white_count++;
JOptionPane.showMessageDialog(this, "白棋胜利");
white_count = 0;
for(i = 0;i 11;i++)//竖向判断
if(chess[j][i] == 1)
if(chess[i + k][j + k] == 1)
if(chess[i - k][j + k] == 1)
void Clear_Chess()
for(int i=0;i11;i++)
for(int j=0;j11;j++)
chess[i][j]=0;
public void paint(Graphics g)
Drawline(g);
Drawchess(g);
public void mouseExited(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public void mouseClicked(MouseEvent e){}
class myframe extends Frame implements WindowListener
mypanel panel;
myframe()
setLayout(null);
panel = new mypanel();
add(panel);
setTitle("单人版五子棋");
addWindowListener(this);
public void windowClosing(WindowEvent e)
System.exit(0);
public void windowDeactivated(WindowEvent e){}
public void windowActivated(WindowEvent e){}
public void windowOpened(WindowEvent e){}
public void windowClosed(WindowEvent e){}
public void windowIconified(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public class mywindow
public static void main(String argc [])
myframe f = new myframe();
第一段:实验题目
五子棋游戏.
第二段:问题分析
第三段:功能设计
我的程序基本功能是实现人机对弈五子棋.人和电脑交替下棋,谁先五子连成一条直线谁就赢.下面是我程序的功能模块:
①等级设置
模拟栈机制实现人悔棋,不限步长的悔棋.对应程序中的悔棋按钮.
根据不同机计算机的屏幕分辨率,绘制逼真的棋盘.
两张古典的人物图片,生动模拟对弈双方.人物图片旁的黑白棋钵图片显示黑白棋归属.
支持用户选择背景,包括棋盘、棋盘边框、窗口边框,彰显个性.
下棋时有棋子落地的声音,一方胜利时有五子连成一片的声音.同时在设置背景时相应的改变整个对弈过程中的背景音乐.
在棋盘正上方有一模拟文本框显示当前棋局用时.
支持和棋、认输、开启新游戏、退出游戏等操作.
第四段:数据结构与算法设计
数据结构部分
①当前棋局的存储结构
基于以上两点,尽管创建动态的顺序表—链表可能可以节省少量内存(可以只存当前有棋的点,原数组对应位置为0的点可以不存),但选择数组的优势完全在上述两点体现了出来.
算法设计部分
Java语言是面向对象的语言.我在进行五子棋游戏编程是总共传创建了11个自定义的类.在编写程序的过程中,我有一个明显的体验就是面向对象编程就是一项有关对象设计和对象接口技术,很多关键的技术就是如何设计自定义的对象.
下面我先概括给出我的所有类的作用:
①mainFrame类:主框架类,我应用程序的入口;
①.0.?chessOneStep类:棋子类,定义每步坐标以及下在该处获得的估价值;
①.1.myCompare类:排序类,完成chessOneStep类的自定义排序
详细设计
①mainFrame类
作为我的五子棋程序的主类,mainFrame类主要实例化相关的对象,如chessbutton,chessborad等,从而完成框架的创建.更重要的是实例化chessposition,这是本程序的核心类,控制游戏双方行棋过程完成人机互动下棋,然后将MyChessPosition与鼠标响应addMouseListener()关联起来.
一个好的游戏必须给人一种身临其境的感觉,而声音是营造这种氛围的重要因素.参照网上各游戏运行商的音乐配置,我选择相关逼真的声音.包括背景音乐、下棋棋子落到棋盘发出的声音以及一方胜出的配乐.所有这些功能的实现,依赖于自定义的chessMusic类,采用AudioInputStream配合Clip的方式完成音乐播放的软硬件工作,然后定义两个接口chessmusic(String?Name)和Stop(),前者完成播放功能,后者完成关闭当前音乐功能.因为音频文件相对较大,而我的程序提供在不同背景乐之间切换的功能,所以在打开另一个音频文件之前必须关闭前一个正在播放的音频文件,防止出现溢出.
适当的动画或图片能给游戏粉丝带来美的体验.所以我的五子棋程序界面在不失和谐的前提下引入了尽可能多的图片,包括对弈双方、棋钵等.图片引入的具体工作通过语句import?javax.imageio.ImageIO完成.同时,由于图片要在用到它的类中被访问,为了避免频繁调用函数,我直接将图片相关联的对象定义为public?static,表明是公用的、静态的.进一步引申开去,我将程序中用到的静态全局变量都定义在chessImage类中.具体如下:
public?static?Date?begin;//每局开始时间
public?static?Date?cur;//每局结束时间
public?static?chessOneStep?LineLeft;//结束端点1
public?static?boolean?IsGameOver;//是否只有一方获胜
public?static?int?WitchMatch;//背景搭配
public?static?String?MusicOfBackGround;//背景音乐
public?static?int?CurrentStep;//记录当前步数
public?static?int?Rank;//设置难度等级
public?static?boolean?IsSurrender;//判断是否认输
public?static?boolean?IsTie;//判断是否认输
public?static?String?Message;//输出提示信息
public?static?Image?IconImage;//?图标
public?static?Image?blackBoard;//白棋盘
public?static?Image?whiteBoard;//黑棋盘
public?static?Image?blackChess;//?白棋棋子图片
public?static?Image?whiteChess;//?白棋棋子图片
public?static?Image?RightPlayer;//白棋棋罐图片
public?static?Image?LeftPlayer;//白棋粉丝头像图片
public?static?String?path?=?"src/";//?图片的保存路径
(1)、按钮组件
在不同的单选按钮前添加相应的文本框,提示用户可以实现的功能.同时我用颜色模拟出显示当前棋局耗用时间的文本框.
不论按钮还是单选按钮都要关联相应的消息,把相应功能的实现放在消息响应处理函数理.这些主要是实现Java库提供的消息响应接口里的方法.
主要完成当前棋面的存储,存储棋面的数据结构为二维数组int[][]?PositionFlag;然后定义获取、设置某点以及整个棋面的状态的方法.
(1)、SetPositionFlag(int?x,?int?y,?int?flag)//设置(x,y)处的状态为flag
由于本类比较重要,所以附上了代码,见源代码1.
方法一:
在需要绘制多像素线条处首先绘制一条单像素线,然后根据线宽要求上下平移适当像素达到绘制多像素的目的.这样的方法适合绘制水平线或竖直线,绘制其他斜率的线条容易造成走样.在没有想到比较好的反走样编程思想后我选择了调用Java库中已经封装好的函数.
方法二:
为了克服方法一绘制非水平或竖直线时造成的走样,同时也为了更进一步学习Java语言,我猜想肯定会有类似OpenGL中设置线宽的画刷,于是上网百度找到了相应的画刷Stroke类.通过Java库实现绘制不同线宽的直线,达到了反走样效果.
这个类是为了配合chessList类实现悔棋以及在计算机下棋算法实现返回有效状态点而设计的.主要数据成员为
private?int?x,y,weight;//其中x,y表示点坐标,weight表示将棋下到该点获得的估价值.
主要方法如下:
(1)、GetX()//获得当前对象的x坐标
程序支持悔棋功能,为了实现悔棋,自定义了chessList类.这个类主要通过引入java.util.ArrayList和java.util.List实现集合的数据类型.然后自定义一些方法,如下:
(1)、AddStep(chessOneStep?OneStep)//添加一步棋到List中
由于每次删除当前List中的最后一个元素,实现后进先出,所以可以模拟栈的功能实现悔棋.
由于在计算机下棋的极大极小博弈树算法中需要对自定义对象chessOneStep按weight进行排序,所以引入了myCompare类,通过实现Comparator接口中的compare方法完成自定义对象排序.
①.0.chessPanel类
程序的自定义面板类,主要负责完成当前框架内容的显示.这是一个重要的与框架和图形显示密切相关的类.主要数据成员为
private?chessboard?MyChessBoard;//当前显示棋盘
private?chesspiece?MyChessPiece;//当前显示整个棋面的状态
(1)、chesspanel(chessboard?MyChessBoard1,?chesspiece?MyChessPiece1)//构造函数,分别用MyChessBoard1和MyChessPiece1初始化MyChessBoard和MyChessPiece
①.1.chessPositon类
private?static?chessboard?MyChessBoard;//当前显示棋盘
public?static?chesspiece?MyChessPiece;//当前显示整个棋面的状态
private?static?chesspanel?Mychesspanel;////当前显示面板
public?static?chesslist?MyChessList=new?chesslist();//当前下棋集合,用于悔棋
public?static?boolean?CanGo;//控制当前下棋一方
类的设计集中体现在成员方法的设计上.实现人机对战,只有语言是远远不够的,还要加入算法,用算法引导计算机下棋.下面介绍该类的方法成员:
(1)、chessposition(chesspanel?,?chessboard?,chesspiece?)?//带有参数的构造函数
不带参数的构造函数
通过调用自定义面板类的显示回调函数用于重新显示游戏界面,达到每下一步棋及时更新游戏界面的目的.
对未连成一片但通过再下一颗子就能连成一片的局面进行估值,这在双方下棋的有限步骤内是能产生重要影响的.如果每局棋仅考虑当前一步,是不可取的.
根据棋面具体情况以及预先设定的估值函数,对某个点对应的局面进行评估.由于每次双方只能下一颗棋,所以可以每次取当前局面的所有点中对应估值最大值点的估值作为整个局面的估值.
计算机下棋方法1,对应难度等级为简单,采用贪心思想.每次下棋前在求得最有利点下棋,而是否最有利只是通过一步评估.算法伪码描述为:
Max取负无穷大
If((i,j)对应的位置无棋)
a.假设放上一颗由人控制的棋,求估价值;
b.假设放上一颗由计算机控制的棋,求估价值;
c.取二者中较大值作为(i,j)处的估价值tmp;
d.取tmp与Max较大值赋值给Max.
最终Max对应的点就是当前整个局面中最大的估值点.至于上述为什么要考虑双方都在该点下棋的情况呢?主要原因为下五子棋是个攻防兼备的过程,不仅要考虑自己对自己最有利,还要考虑对对手最不利,通俗来讲就是在自己赢的时候不能让对手先赢.
(10)、GetSearchNext(int?LookLength)
derectSearch(int?[][]Array,boolean?who,int?deepth)
a.采用深度优先搜索需要递归,递归中状态过多可能会爆栈,我们知道递归是用栈机制来实现的;采用宽度优先搜索又需要存储为扩展的节点,这对内存容量要求很高.
直接搜索算法伪代码为
GetSearch(boolean?flag,int?deep)
如果deep等于0,返回当前棋局估值;
GetSearch(!flag,deep-1);
如果轮到人下棋,置标志位为1;
(11)、GetMinMaxsearchNext(int?LookLength)
MinMaxsearch(int?[][]Array,boolean?who,?int?deepth)
至于扑克游戏的编写,主要是规则和逻辑的编写,其余的还没什么.
package game;
/*这是一个双人贪吃蛇游戏
*粉丝一 A S D W 控制方向
*粉丝二 上下左右 控制方向
*当某粉丝无路可走的时候既输
*/
public class HsGame extends JFrame {
HsGame(String str) {
// 设置主面版
this.setTitle(str);
MyPanel mp = new MyPanel();
this.add(mp);
this.addKeyListener(mp);
new Thread(mp).start();
// 主线程
HsGame m = new HsGame("贪吃蛇竞技版");
m.setVisible(true);
class MyPanel extends JPanel implements Runnable, KeyListener {
// 设置线程休眠时间
// 设置初始方向
MyPanel() {
// 初始化界面
s1[ix][iy] = 0;
// 设置边界
// 上下边界
s1[ix][0] = 1;
// 左右边界
s1[0][iy] = 1;
// 画板
public void paint(Graphics g) {
// 显示粉丝一
g.setColor(Color.red);
if (s1[ix][iy] == 1) {
// 显示粉丝二
g.setColor(Color.blue);
// 画出边界
g.setColor(Color.black);
public void run() {
while (true) {
switch (fangxiang1) {
case 0:
x1--;
break;
case 1:
y1--;
x1++;
y1++;
// 判断死活
JOptionPane.showMessageDialog(null,
"Game Over !", JOptionPane.ERROR_MESSAGE);
// 结束游戏
s1[x1][y1] = 1;
// 弹出player1胜利对话框
"player 1 win!",
try {
Thread.sleep(sleep);
} catch (Exception e) {
e.printStackTrace();
// 重画
this.repaint();
public void keyTyped(KeyEvent e) {
public void keyPressed(KeyEvent e) {
// 粉丝一控制
fangxiang1 = 0;
System.out.println("player 1 left");
fangxiang1 = 1;
System.out.println("player 1 up");
if (fangxiang1 != 0) {
System.out.println("player 1 right");
if (fangxiang1 != 1) {
System.out.println("player 1 down");
// 粉丝二控制
public void keyReleased(KeyEvent e) {