博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
俄罗斯方块一个实例
阅读量:2439 次
发布时间:2019-05-10

本文共 16180 字,大约阅读时间需要 53 分钟。

这个也比较像,主要借鉴消行的处理

/* 俄罗斯方块人工智能版 *//* 作者:wzb32 *//* Copyright(C) 2007.11 - 2007.12 *//*导入类包*/import java.awt.*;import java.applet.*;import java.awt.event .*;/*创建一个从Applet派生并实现Runnable和ItemListener接口的用于被浏览器加载的类*/public class WzbEluosi extends Applet implements Runnable,ItemListener{    final int GameStart = 0;  //游戏开始状态    final int GameGoing = 1;  //游戏进行状态    final int GameStop = 2;  //游戏暂停状态    final int GameAuto = 3;  //游戏自动打状态    int gamestate = GameStart;  //定义游戏初始状态    private Image bgImage;  //这里声明bgImage和bg两个实例变量用来存储后台图画    private Graphics bg;  //目的是为了采用双缓冲机制来解决屏幕的闪烁现象    int width = 12;  //定义游戏一行的格子数    int height = 20;  //定义游戏一列的格子数    int frameX = 150;  //定义程序框架打印到屏幕上的x坐标    int frameY = 30;  //定义程序框架打印到屏幕上的y坐标    int frameSize = 20;  //定义程序框架的大小    int[][] map = new int[31][38];  //定义一个储存布局的点阵数据的二维数组    int x, y;  //方块的坐标    int type, shape;  //当前方块的类型和形态    int typeNext, shapeNext;  //下一个方块的类型和形态    int level;  //等级,包含方块下落速度和方块自动上移的速度    int scoreLevel;  //分数与等级的联系    long score;  //记录分数    int fallTime;  //方块下落一格的时间    String ordinaryEasy;  //根据用户选择的难度判断方块是否自动上升的变量    int blockUpTime;  //定义方块自动整体上移一格的时间    byte upStyle;  //定义方块上移的两种方式    int xBest;  //当前方块的最佳下落的x坐标    int xBest2;  //下一个方块的最佳下落x坐标    int shapeBest, shapeBest2;  //当前方块和下个一个方块的最佳形态    int xblockDownMove,yblockDownMove;  //当前方块在下落完成后移动的最佳坐标    int xblockDownMove2,yblockDownMove2;  //当前方块在下落完成后移动的最佳坐标    int xAutoMoveTime;  //方块的自动移动一次的时间    int autoSwitch;  //自动移动的类型转换    int bug;  //一个郁闷了我很久的bug,熬了个通宵都没解决,感觉特莫名其妙,在做了多个测试之后,经过反复的思想斗争,最终用了一个不	负责的方法解决了T_T     		final Color []colors = 	{Color.white,Color.red,Color.blue,Color.green,Color.magenta,Color.orange,Color.pink,Color.cyan,Color.darkGray};//颜色数组    final byte [][][][]block =   //定义一个四维数组储存七种方块类型和方块四种形态的数据,一个方块存储在一个4*4正方形容器里    {        {            {
{1,0,0,0},{1,0,0,0},{1,0,0,0},{1,0,0,0}}, //形态1 ■ {
{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,1,1,1}}, //形态2 ■ {
{1,0,0,0},{1,0,0,0},{1,0,0,0},{1,0,0,0}}, //形态3 ■ {
{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,1,1,1}} //形态4 ■ } , { {
{0,0,0,0},{0,0,0,0},{1,1,0,0},{1,1,0,0}}, //形态1 {
{0,0,0,0},{0,0,0,0},{1,1,0,0},{1,1,0,0}}, //形态2 ■■ {
{0,0,0,0},{0,0,0,0},{1,1,0,0},{1,1,0,0}}, //形态3 ■■ {
{0,0,0,0},{0,0,0,0},{1,1,0,0},{1,1,0,0}} //形态4 } , { {
{0,0,0,0},{0,0,0,0},{1,1,0,0},{0,1,1,0}}, //形态1 {
{0,0,0,0},{0,1,0,0},{1,1,0,0},{1,0,0,0}}, //形态2 ■■ {
{0,0,0,0},{0,0,0,0},{1,1,0,0},{0,1,1,0}}, //形态3 ■■ {
{0,0,0,0},{0,1,0,0},{1,1,0,0},{1,0,0,0}} //形态4 } , { {
{0,0,0,0},{0,0,0,0},{0,1,1,0},{1,1,0,0}}, //形态1 {
{0,0,0,0},{1,0,0,0},{1,1,0,0},{0,1,0,0}}, //形态2 ■■ {
{0,0,0,0},{0,0,0,0},{0,1,1,0},{1,1,0,0}}, //形态3 ■■ {
{0,0,0,0},{1,0,0,0},{1,1,0,0},{0,1,0,0}} //形态4 } , { {
{0,0,0,0},{0,0,0,0},{1,0,0,0},{1,1,1,0}}, //形态1 {
{0,0,0,0},{1,1,0,0},{1,0,0,0},{1,0,0,0}}, //形态2 ■ {
{0,0,0,0},{0,0,0,0},{1,1,1,0},{0,0,1,0}}, //形态3 ■■■ {
{0,0,0,0},{0,1,0,0},{0,1,0,0},{1,1,0,0}} //形态4 } , { {
{0,0,0,0},{0,0,0,0},{0,0,1,0},{1,1,1,0}}, //形态1 {
{0,0,0,0},{1,0,0,0},{1,0,0,0},{1,1,0,0}}, //形态2 ■ {
{0,0,0,0},{0,0,0,0},{1,1,1,0},{1,0,0,0}}, //形态3 ■■■ {
{0,0,0,0},{1,1,0,0},{0,1,0,0},{0,1,0,0}} //形态4 } , { {
{0,0,0,0},{0,0,0,0},{1,1,1,0},{0,1,0,0}}, //形态1 {
{0,0,0,0},{0,1,0,0},{1,1,0,0},{0,1,0,0}}, //形态2 ■■■ {
{0,0,0,0},{0,0,0,0},{0,1,0,0},{1,1,1,0}}, //形态3 ■ {
{0,0,0,0},{1,0,0,0},{1,1,0,0},{1,0,0,0}} //形态4 } }; /*程序首次启动时首先自动调用的用于初始化的函数*/ public void init() { reNew(); //初始化数据 modeSelect(); //游戏开始前让用户选择模式 bgImage = createImage(this.getSize().width, this.getSize().height); //新建一个后台图像类变量 bg = bgImage.getGraphics(); //得到当前图像的图形关联 } /*定义初始化数据的函数*/ public void reNew() { blockUpTime = 0; //初始化方块上移时间 score = 0; //初始化分数 scoreLevel = 0; upStyle = (byte) (Math.random() * 2); //随机给upStyle赋一个小于2的正整数值 for (int j=0; j
< 5 ? 5 : width > 38 ? 38 : width; //限定width的范围 height = height < 5 ? 5 : height > 27 ? 27 : height; //限定height的范围 remove(bt2); remove(bt1); remove(cb1); remove(cb2); remove(cb3); remove(c); remove(tf1); remove(bt3); //删除 全部列表和按钮 add(bt2); add(bt1); add(cb1); add(cb2); add(cb3); add(c); add(tf1); add(bt3); //加入全部列表和按钮 reNew(); //初始化所有数据 gamestate = GameGoing; //让游戏状态为进行中 bt2.setLabel(" 暂停 "); bt3.setLabel("高手汪汪狗表演"); } }); bt2.addActionListener(new ActionListener() //建立按钮2对象的监听者 { public void actionPerformed(ActionEvent e) //当用户按下按钮2产生的事件,是个内部类 { if (gamestate == GameGoing || gamestate == GameAuto) { bt2.setLabel(" 继续 "); //设置按钮名称 bt3.setLabel("高手汪汪狗表演"); gamestate = GameStop; //设置游戏状态为暂停 } else if (gamestate == GameStop) { bt2.setLabel(" 暂停 "); //设置按钮名称 gamestate = GameGoing; //设置游戏状态为进行中 } remove(bt2); remove(bt1); remove(cb1); remove(cb2); remove(cb3); remove(c); remove(bt3); //删除全部列表和按钮 add(bt2); add(bt1); add(cb1); add(cb2); add(cb3); add(c); add(bt3); //加入全部列表和按钮 } }); bt3.addActionListener(new ActionListener() //建立按钮3对象的监听者 { public void actionPerformed(ActionEvent e) //当用户按下按钮3产生的事件,是个内部类 { if (gamestate == GameStart || gamestate == GameGoing) { bt3.setLabel("我是菜鸟我怕谁"); //设置按钮名称 autoSwitch = 0; autoPlayCurrent(); //计算当前方块的最佳下落方法和坐标 gamestate = GameAuto; //设置游戏状态为自动 } else if (gamestate == GameAuto) { bt3.setLabel("高手汪汪狗表演"); //设置按钮名称 gamestate = GameGoing; //设置游戏状态为进行中 } remove(bt3); remove(bt1); remove(cb1); remove(cb2); remove(cb3); remove(c); remove(bt2); //删除全部列表和按钮 add(bt3); add(bt1); add(cb1); add(cb2); add(cb3); add(c); add(bt2); //加入全部列表和按钮 } }); } public void itemStateChanged(ItemEvent e) //覆盖ItemListener接口中的抽象函数,抽象的函数必须要重新定义 { } /*程序调用init()之后自动调用这个函数*/ public void start() { Thread th = new Thread(this); //定义一个新的线程,控制方块下落 th.start(); //启动此线程 } /*创建线程对象的实例时自动调用的一个抽象函数*/ public void run() { final int[] speed = {300000,300000,250000,150000,100000,80000,50000,20000,7000,0}; while (true) //设置个死循环 { switch (gamestate) //根据游戏状态选择分支程序运行 { case GameAuto : if (((width > 20 || height < 6) && level == 9) || ordinaryEasy == "困难" || level == 9) { x = xBest; shape = shapeBest; } if (xAutoMoveTime >= speed[level]) { if (x < xBest) x++; //方块水平移动到最佳下落x坐标 if (x > xBest) x--; if (shape != shapeBest) //方块变换成最佳形态 { shape++; if (shape == 4) shape = 0; } xAutoMoveTime = 0; } if (xblockDownMove != xBest && y == yblockDownMove) { x = xblockDownMove; //方块下落完成时移动到最佳x坐标 } xAutoMoveTime++; //方块自动移动时间自增 case GameGoing : try //抛出一个异常 { //暂停方块下落线程在一个等待时间内,这里是1ms Thread.sleep(1); //这里必须要让线程暂停一下,不然autoPlay()方法的调用会对程序运行的速度影响非常大,暂停一 下又没有影响了 } //反正感觉莫名其妙,估计是线程时间片的问题吧,当时郁闷了我N久N久啊,苯死我拉,啊啊,不过后来又莫名其妙的解决了, 我真是个天才,哈哈 catch (Exception e) //捕获异常 { } if (ordinaryEasy == "普通" || ordinaryEasy == "困难") blockUpTime++; //方块自动上移时间自增 if (gamestate == GameAuto && x == xBest && shape == shapeBest) { int z = level < 9 ? 8 : 9; if (fallTime > speed[z]) fallBlock(); //调用方块下落方法 } else if (fallTime > speed[level]) fallBlock(); //调用方块下落方法 fallTime++; //方块下落时间自增 repaint(); //刷新屏幕 break; case GameStop : break; } } } /*在Applet界面上进行相应的绘画动作的函数*/ public void paint(Graphics g) { bg.clearRect(0,0,getSize().width,getSize().height); drawInfo(bg); //将程序的框架和基本信息存储到后台 if(gamestate == GameGoing || gamestate == GameStop || gamestate == GameAuto) { drawBlock(bg); //在后台绘制方块 drawNextBlock(bg); //在后台绘制下一个方块 } g.drawImage(bgImage, 0, 0, this); //将后台存储的图画打印到屏幕上来 } /*调用repaint()方法时自动调用此函数,因为原此函数会清屏,造成屏幕闪烁,所以要重写此函数*/ public void update(Graphics g) { paint(g); //调用paint方法 } /*定义打印程序的框架和基本信息的函数*/ public void drawInfo(Graphics g) { if (scoreLevel > 9999) //计算等级 { level++; scoreLevel -= 10000; } if (level > 9) level = 9; //限定等级范围 g.setColor(Color.black); //设置颜色 g.drawRect(frameX-1, frameY-1, frameSize*width+1, frameSize*height+1); //绘制界面大方框 g.drawString("NEXT", frameX+frameSize*(width+1), frameY+25); g.drawRect(frameX+frameSize*(width+1), frameY+25, 80, 80); //绘制显示下一个方块的方框 g.drawString("LEVEL", frameX+frameSize*(width+1), frameY+125); g.drawRect(frameX+frameSize*(width+1), frameY+125, 80, 20); //绘制显示等级的方框 g.drawString(String.valueOf(level), frameX+frameSize*(width+1)+1, frameY+141); //绘制等级 g.drawString("SCORE", frameX+frameSize*(width+1), frameY+165); g.drawRect(frameX+frameSize*(width+1), frameY+165, 80, 20); //绘制显示分数的方框 g.drawString(String.valueOf(score), frameX+frameSize*(width+1)+1, frameY+181); //绘制分数 g.drawString("操作:↑↓←→", frameX+frameSize*(width+1), frameY+250); g.drawString("暂停:P", frameX+frameSize*(width+1), frameY+270); g.drawString("作者:wzb32", frameX+frameSize*(width+1), frameY+305); g.drawString("QQ:103168834", frameX+frameSize*(width+1), frameY+325); g.drawString("Email:wzb32@qq.com", frameX+frameSize*(width+1), frameY+345); g.drawString("版本:v1.00", frameX+frameSize*(width+1), frameY+365); g.drawString("Copyright(C) 2007.11 - 2007.12", frameX+frameSize*(width+1), frameY+385); for (int j=4; j
3) //判断此格是否要绘制一个小小方块 { g.setColor(colors[type+1]); //设定方块颜色 g.fill3DRect(frameX+x*frameSize+i*frameSize, frameY+y*frameSize+j*frameSize-4*frameSize, frameSize, frameSize, true); g.fill3DRect(frameX+x*frameSize+i*frameSize+1, frameY+y*frameSize+j*frameSize+1-4*frameSize, frameSize-2, frameSize-2, true); } } } } /*定义方块下落的函数*/ public void fallBlock() { if (!moveFit(x, y+1)) //判断方块将向下移动的一格是否能移动 { fallOver(); //下落完成 if(ordinaryEasy == "困难") { if (blockUpTime > 3000000) blockAllUp(); //方块整体自动上移一格 } else if (blockUpTime > 6999999) blockAllUp(); //普通模式的方块自动上移 } y++; //方块下落一格 fallTime=0; } /*定义方块下落完成的函数*/ public void fallOver() { for (int j=0; j<4; j++) { for (int i=0; i<4; i++) { if (block[type][shape][j][i] == 1) //一个方块存储在一个4*4正方形容器里,判断容器里这个位子是否有小小方块 { map[y+j][x+i] = type + 1; //将当前方块的坐标数据存储到布局的点阵里 if (y + j < 5) gamestate = GameStart; //方块超出上界,游戏结束 } } } if(gamestate == GameStart) { y--; return; } RemoveRow(); //调用消行函数 if (gamestate == GameAuto) { switch (autoSwitch) { case 0: type = typeNext; //将下一个方块类型覆盖当前方块类型 shape = shapeNext; //将下一个方块形态覆盖当前方块形态 x = width / 2 - 1; //初始化方块的坐标 y = 0; autoPlayCurrent(); //计算当前方块的最佳下落方法 typeNext = type; shapeNext = shape; shapeBest2 = shapeBest; xBest2 = xBest; xblockDownMove2 = xblockDownMove; yblockDownMove2 = yblockDownMove; autoPlayNext(); //计算下一个方块的最佳下落方法 autoSwitch++; break; case 1: shapeBest = shapeBest2; xBest = xBest2; xblockDownMove = xblockDownMove2; yblockDownMove = yblockDownMove2; nextBlockUpdate(); //更新下一个方块的数据 autoSwitch = 0; break; } } else nextBlockUpdate(); //刷新下一个方块的数据 } /*定义绘制下一个方块的函数*/ public void drawNextBlock(Graphics g) { g.setColor(colors[typeNext+1]); for (int j=0; j<4; j++) { for (int i=0; i<4; i++) { if (block[typeNext][shapeNext][j][i] == 1) //一个方块存储在一个4*4正方形容器里,判断容器里这个位子是否有小方 块 { g.fill3DRect(frameX+i*16+frameSize*(width+1)+9, frameY+j*16+29, 16, 16, true); g.fill3DRect(frameX+i*16+frameSize*(width+1)+10, frameY+j*16+30, 14, 14, true); } } } } /*更新下一个方块数据的函数*/ public void nextBlockUpdate() { type = typeNext; //将下一个方块类型覆盖当前方块类型 shape = shapeNext; //将下一个方块形态覆盖当前方块形态 typeNext = (int) (Math.random() * 7); //初始化下一个方块类型 shapeNext = (int) (Math.random() * 4); //初始化下一个方块形态 x = width / 2 - 1; //初始化方块的坐标 y = 0; } /*判断方块下一步的移动是否可行的函数*/ public boolean moveFit(int xmove, int ymove) { for (int j=0; j<4; j++) { for (int i=0; i<4; i++) { if (block[type][shape][j][i] == 1) //一个方块存储在一个4*4正方形容器里,判断容器里这个位子是否有小小方块 { if (xmove + i < 0 || xmove+i > width - 1 || ymove < 0 || ymove+j > height + 3 || (map[ymove+j][xmove+i] != 0)) return false; //不能移动 } } } return true; //能移动 } /*定义消行的函数*/ public void RemoveRow() { int rowSmallBlockNum; //定义一个保存当行已有多少的方块的变量 int reMoveRowNum = 0; //定义一个保存一次共消去多少行的变量 int sc[] = {0,100,300,700,1200}; //定义一个存储分数的数组 for(int j=0; j<4; j++) { rowSmallBlockNum = 0; for (int i=0; i
1; jj--) { for (int ii=0; ii
1; jj--) { for (int ii=0; ii
5) emptyBlockNum=999; //根据当前情况采取不同的进攻或防守策略 if (ordinaryEasy != "困难" && xCopy == xMoveMax && !hasEmptyBlock && topRowAll > 7 && reMoveRowNum < 3) emptyBlockNum=999; if (topRowAll*aRam[as] + reMoveRowNum*aRam[zc] - emptyBlockNum*aRam[da] + yCopy > valueMax) //当前局面的评估方程 { valueMax = topRowAll*aRam[as] + reMoveRowNum*aRam[zc] - emptyBlockNum*aRam[da] + yCopy; if (xCopyCopy == xCopy) //保存到当前最佳的下落方法的数据 { xBest2 = xCopy; } else { xBest2 = xCopyCopy; yblockDownMove2 = yCopy; } shapeBest2 = shape; xblockDownMove2 = xCopy; } for (int i=0; i
7 && reMoveRowNum < 3) emptyBlockNum=999; if (topRowAll*aRam[as] + reMoveRowNum*aRam[ws] - emptyBlockNum*aRam[cx] + yCopy > valueMax) //当前局面的评估方程 { valueMax = topRowAll*aRam[as] + reMoveRowNum*aRam[ws] - emptyBlockNum*aRam[cx] + yCopy; if (xCopyCopy == xCopy) //保存当前方块的最佳下落方法的数据 { xBest = xCopy; } else { xBest = xCopyCopy; yblockDownMove = yCopy; } xblockDownMove = xCopy; shapeBest = shape; } for (int j=0; j<4; j++) //把刚才储存到布局里的点全部去除 for (int i=0; i<4; i++) if (block[type][shape][j][i] == 1) map[yCopy+j][xCopy+i] = 0; } xCopy= xCopyCopy; } } type = typeCopy; shape = shapeCopy; }}

转载地址:http://amcqb.baihongyu.com/

你可能感兴趣的文章
Gentoo 2005.1 完整的USE参数清单中文详解(转)
查看>>
如何在嵌入式Linux产品中做立体、覆盖产品生命期的调试 (5)
查看>>
手机最新触控技术
查看>>
Kubuntu 项目遭遇困难(转)
查看>>
kubuntu使用日记之 eva的配置使用(转)
查看>>
unix下几个有用的小shell脚本(转)
查看>>
QQ病毒的系列处理办法(转)
查看>>
source命令的一个妙用(转)
查看>>
Red Hat并购JBoss 谁将受创?(转)
查看>>
基于IBM大型主机,Linux开辟意大利旅游新天地(转)
查看>>
一些Linux试题(经典!!)(转)
查看>>
优化MySQL数据库性能的八大“妙手”(转)
查看>>
福布斯:Sun下场本可避免 老CEO不听劝(转)
查看>>
根据什么选择一套适合自己的linux系统?(转)
查看>>
戴尔将在法国推出Linux笔记本(转)
查看>>
近9成盗版Office用户称愿投奔开源(转)
查看>>
MySQL购InnoDB不敌甲骨文宣布开放数据引擎(转)
查看>>
银行监会选红旗Linux建设公文传输系统(转)
查看>>
红旗支撑国家外汇管理局网上核销系统(转)
查看>>
网上交易中帐号和密码被盗的解决途径(转)
查看>>