当前位置: 首页 > news >正文

项目历程—生命数组游戏(两版本)

实现效果

(一)版本1:

生命数组游戏


效果截图1:
在这里插入图片描述
截图2:
在这里插入图片描述

(二)版本2:

生命数组游戏2

代码实现:

(一)版本一:

(一)创建AI方法类:

内含方法
1.显现数组
2.初始化数组
3.更新数组
4.计算此处是否可存活
5.备份上一次数组
6.判断这一次数组和上一次数组是否相同

5和6方法是为了检测生命数组是否停止更新用的

package DemoProject.fjm0729_V1;import java.util.Random;public class AILife {static  int g=1;public  static void showUpdate(int [][] LifeArr){upDate(LifeArr);//输出更迭后的数组System.out.println("更新过"+ g++ + "次的数组生命数组为:");for(int i = 0 ; i < LifeArr.length ; i++){for(int j = 0 ; j < LifeArr[i].length ; j ++){System.out.print(LifeArr[i][j] + "  ");if ( j == LifeArr[i].length-1 ){System.out.println();}}}}public static void randomInit(int [][] LifeArr){Random random = new Random();for(int i = 0 ; i < LifeArr.length ; i++){for(int j = 0 ; j < LifeArr[i].length ; j ++){int randomValue = random.nextBoolean() ? 0 : 1;LifeArr[i][j] = randomValue;}}}public static  void upDate(int [][] LifeArr){int [][] CalIsAliveArr = CalSurroundAlive(LifeArr);for( int i = 0 ; i < CalIsAliveArr.length ; i++){for ( int j = 0 ; j < CalIsAliveArr[i].length ; j ++){//条件3if(LifeArr[i][j] == 0){if(CalIsAliveArr[i][j] == 3 ){LifeArr[i][j] = 1;}}else if(LifeArr[i][j] == 1){//条件2if(CalIsAliveArr[i][j] == 3 || CalIsAliveArr[i][j] == 2){LifeArr[i][j] = 1;//条件1}else if(CalIsAliveArr[i][j] > 3 || CalIsAliveArr[i][j] < 2){LifeArr[i][j] = 0;}}}}}public  static int [][] CalSurroundAlive(int [][] LifeArr){int [][] CalIsAliveArr = new int[LifeArr.length][LifeArr[0].length];for( int i = 0 ; i < LifeArr.length ; i ++ ){// i为行 j为列for ( int j = 0 ; j < LifeArr[i].length ;  j ++ ){//判断该点是否活着://如果上方有东西,则向上遍历,如此推广到四个方向int count = 0;if( i - 1 >= 0){if(LifeArr[i-1][j] == 1){count++;}}if( i + 1 < LifeArr.length ){if(LifeArr[i+1][j] == 1){count++;}}if( j + 1 < LifeArr[i].length){if(LifeArr[i][j+1] == 1){count++;}}if( j - 1 >= 0){if(LifeArr[i][j-1] == 1){count++;}}CalIsAliveArr[i][j] = count;}}return CalIsAliveArr;}//备份上一次数组public static int [][] backUpArr(int [][] LifeArr){int [][] Arr = new int[LifeArr.length][LifeArr[0].length];for(int i = 0 ; i < LifeArr.length ; i++){for(int j = 0 ; j < LifeArr[i].length ; j ++){Arr[i][j] = LifeArr[i][j];}}return Arr;}//判断数组元素是否相同public boolean JudgeSame(int [][] backUpArr , int [][] LifeArr){for(int i = 0 ; i < LifeArr.length ; i++){for(int j = 0 ; j < LifeArr[i].length ; j ++){if(backUpArr[i][j]  !=  LifeArr[i][j] ){return false;}}}return true;}}

(二)创建主界面类:

package DemoProject.fjm0729_V1;import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Scanner;public class GameUI extends JFrame {int [][] LifeArr = null;int n = 0;public void showUI(){System.out.println("欢迎来到生命数组游戏!");Scanner scanner=new Scanner(System.in);System.out.print("请输入生命数组的行数:");int row=scanner.nextInt();System.out.print("请输入生命数组的列数:");int col=scanner.nextInt();System.out.println("输入成功!等待生命数组加载.....");LifeArr=new int[row][col];AILife.randomInit(LifeArr);System.out.println("生命数组初始化....");for(int i = 0 ; i < LifeArr.length ; i++){for(int j = 0 ; j < LifeArr[i].length ; j ++){System.out.print(LifeArr[i][j] + "  ");if ( j == LifeArr[i].length-1 ){System.out.println();}}}setTitle("生命游戏");setSize(900,900);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setLocationRelativeTo(null);setVisible(true);while (true){try {Thread.sleep(400);} catch (InterruptedException e) {throw new RuntimeException(e);}repaint();}}public void paint(Graphics g){BufferedImage bfi = new BufferedImage(900,820,BufferedImage.TYPE_4BYTE_ABGR);Graphics graphics = bfi.getGraphics();graphics.setColor(Color.WHITE);graphics.fillRect(0,0,900,820);AILife.showUpdate(LifeArr);graphics.setColor(Color.BLACK);//绘制更迭图像(1次)for(int i = 0 ; i < LifeArr.length ; i++){for(int j = 0 ; j < LifeArr[i].length ; j ++){if(LifeArr[i][j] ==1 ){graphics.fillRect(  i*9, 40+j*8,9,8);}}}System.out.println("重绘了" + ++n + "次");g.drawImage(bfi,0,0,null);}public static void main(String[] args) {new GameUI().showUI();}
}

注意:
1.不要使用for循环来重绘,因为只有最后一次循环里,paint()方法才会被执行。这涉及到repaint的异步机制,不会立即进入paint()方法中
2.Buffered.TYPE_4BYTE_ABGR为透明背景,因此需要每一次绘制,都需要先画一个与窗口齐宽高的白色面板,覆盖掉先前痕迹

(二)版本二:

(一)创建AI方法类:

package DemoProject.fjm0729_V2;import java.util.Random;public class AILife {static  int g=1;public  static void showUpdate(int [][] LifeArr){upDate(LifeArr);//输出更迭后的数组System.out.println("更新过"+ g++ + "次的数组生命数组为:");for(int i = 0 ; i < LifeArr.length ; i++){for(int j = 0 ; j < LifeArr[i].length ; j ++){System.out.print(LifeArr[i][j] + "  ");if ( j == LifeArr[i].length-1 ){System.out.println();}}}}public static void randomInit(int [][] LifeArr){Random random = new Random();for(int i = 0 ; i < LifeArr.length ; i++){for(int j = 0 ; j < LifeArr[i].length ; j ++){int randomValue = random.nextBoolean() ? 0 : 1;LifeArr[i][j] = randomValue;}}}public static  void upDate(int [][] LifeArr){int [][] CalIsAliveArr = CalSurroundAlive(LifeArr);for( int i = 0 ; i < CalIsAliveArr.length ; i++){for ( int j = 0 ; j < CalIsAliveArr[i].length ; j ++){//条件3if(LifeArr[i][j] == 0){if(CalIsAliveArr[i][j] == 3 ){LifeArr[i][j] = 1;}}else if(LifeArr[i][j] == 1){//条件2if(CalIsAliveArr[i][j] == 3 || CalIsAliveArr[i][j] == 2){LifeArr[i][j] = 1;//条件1}else if(CalIsAliveArr[i][j] > 3 || CalIsAliveArr[i][j] < 2){LifeArr[i][j] = 0;}}}}}public  static int [][] CalSurroundAlive(int [][] LifeArr){int [][] CalIsAliveArr = new int[LifeArr.length][LifeArr[0].length];for( int i = 0 ; i < LifeArr.length ; i ++ ){// i为行 j为列for ( int j = 0 ; j < LifeArr[i].length ;  j ++ ){//判断该点是否活着://如果上方有东西,则向上遍历,如此推广到四个方向int count = 0;if( i - 1 >= 0){if(LifeArr[i-1][j] == 1){count++;}}if( i + 1 < LifeArr.length ){if(LifeArr[i+1][j] == 1){count++;}}if( j + 1 < LifeArr[i].length){if(LifeArr[i][j+1] == 1){count++;}}if( j - 1 >= 0){if(LifeArr[i][j-1] == 1){count++;}}CalIsAliveArr[i][j] = count;}}return CalIsAliveArr;}//备份上一次数组public static int [][] backUpArr(int [][] LifeArr){int [][] Arr = new int[LifeArr.length][LifeArr[0].length];for(int i = 0 ; i < LifeArr.length ; i++){for(int j = 0 ; j < LifeArr[i].length ; j ++){Arr[i][j] = LifeArr[i][j];}}return Arr;}//判断数组元素是否相同public boolean JudgeSame(int [][] backUpArr , int [][] LifeArr){for(int i = 0 ; i < LifeArr.length ; i++){for(int j = 0 ; j < LifeArr[i].length ; j ++){if(backUpArr[i][j]  !=  LifeArr[i][j] ){return false;}}}return true;}}

(二)创建监听器类:一方面是鼠标监听器,一方面是键盘监听器

package DemoProject.fjm0729_V2;import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;public class EleListener implements MouseListener, KeyListener {GameUI gameUI;public EleListener( GameUI gameUI){this.gameUI=gameUI;}@Overridepublic void mouseClicked(MouseEvent e) {}@Overridepublic void mousePressed(MouseEvent e) {System.out.println("鼠标可监听");int x = e.getX();//决定的是第几列int y = e.getY();//决定的是第几行int row = (y - 20) / 8;         //决定第几行int col = x / 9;         //决定第几列System.out.println("这是第" + row + "行第" + col + "列");gameUI.LifeArr[row][col] = 1;}@Overridepublic void mouseReleased(MouseEvent e) {}@Overridepublic void mouseEntered(MouseEvent e) {}@Overridepublic void mouseExited(MouseEvent e) {}@Overridepublic void keyTyped(KeyEvent e) {}@Overridepublic void keyPressed(KeyEvent e) {int Key = e.getKeyCode();switch (Key){case KeyEvent.VK_SPACE:System.out.println("键盘被点击");gameUI.state = 1;}}@Overridepublic void keyReleased(KeyEvent e) {}
}

总结:
1.通过鼠标监听器,监听鼠标位置,将鼠标位置转换成其落在数组内的位置。将此空赋值为1
2.通过键盘监听器,控制运行状态,一开始向数组内赋值,后续使用键盘控制数组的开启
(三)创建主界面

package DemoProject.fjm0729_V2;import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Scanner;public class GameUI extends JFrame {int [][] LifeArr = null;int n = 0;int state = 0;int ImageX = 900;int ImageY = 820;public void showUI(){EleListener el = new EleListener(this);System.out.println("欢迎来到生命数组游戏!");Scanner scanner=new Scanner(System.in);System.out.print("请输入生命数组的行数:");int row=scanner.nextInt();System.out.print("请输入生命数组的列数:");int col=scanner.nextInt();System.out.println("输入成功!等待生命数组加载.....");LifeArr=new int[row][col];System.out.println("生命数组初始化....");setTitle("生命游戏");setSize(900,900);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setLocationRelativeTo(null);addKeyListener(el);addMouseListener(el);setVisible(true);while (true){if(state == 1){System.out.println("本代码被执行");}else if(state == 0){System.out.println("值未被改变");}try {Thread.sleep(400);} catch (InterruptedException e) {throw new RuntimeException(e);}repaint();}}public void paint(Graphics g){if(state == 1){System.out.println("传进来了" + CalAllEle(LifeArr) + "值");if(JudgeHave(LifeArr)){System.out.println("LifeArr被传进来值了");}BufferedImage bfi = new BufferedImage(ImageX,ImageY,BufferedImage.TYPE_4BYTE_ABGR);Graphics graphics = bfi.getGraphics();graphics.setColor(Color.WHITE);graphics.fillRect(0,0,ImageX,ImageY);AILife.showUpdate(LifeArr);graphics.setColor(Color.BLACK);//绘制更迭图像(1次)for(int i = 0 ; i < LifeArr.length ; i++){for(int j = 0 ; j < LifeArr[i].length ; j ++){if(LifeArr[i][j] ==1 ){graphics.fillRect(  i*9, 20+j*8,9,8);}}}System.out.println("重绘了" + ++n + "次");g.drawImage(bfi,0,0,null);}}public boolean JudgeHave(int [][] LifeArr){for (int i = 0 ; i < LifeArr.length ; i++){for( int j = 0 ; j < LifeArr[0].length ; j ++){if(LifeArr[i][j] == 1){return true;}}}return false;}public int CalAllEle(int [][] LiffeArr){int count = 0;for (int i = 0 ; i < LifeArr.length ; i ++){for ( int j = 0 ; j < LifeArr[0].length ; j ++){if(LifeArr[i][j] == 1){count++;}}}return count;}public static void main(String[] args) {new GameUI().showUI();}
}

删改处:将面板的坐标及大小转换成一个变量
增加处:添加监听器,并在循环中加入**Thread.sleep()**方法,不仅仅是为了减缓重绘速度,更是为了使EDT(事件调度线程)不要过于堵塞,确保其能及时监听到鼠标事件。
(个人提议)
手动初始化数组,很累。因为有10000个空位,填充起来需要点好多次鼠标,并且更迭起来又会淘汰掉一大批零散的空位

http://www.xdnf.cn/news/1211401.html

相关文章:

  • Vulkan入门教程 | 第二部分:创建实例
  • “非参数化”大语言模型与RAG的关系?
  • 并查集介绍及典型应用和编程题
  • [Linux入门] Linux 部署本地 APT 仓库及 NFS 共享服务全攻略
  • ITIL 4 高速IT:解耦架构——构建快速迭代的技术基座
  • 【LeetCode 随笔】
  • centos7安装Docker
  • 基于三台主机搭建 Web 服务环境:Nginx、NFS 与 DNS 配置全流程
  • 【牛客网C语言刷题合集】(五)——主要二进制、操作符部分
  • SQL158 每类视频近一个月的转发量/率
  • C++:stack与queue的使用
  • Leetcode-3152 特殊数组 II
  • 进阶向:Manus AI与多语言手写识别
  • 【Spring AI 1.0.0】Spring AI 1.0.0框架快速入门(5)——Tool Calling(工具调用)
  • scrapy框架新浪新闻
  • 【大语言模型入门】—— Transformer 如何工作:Transformer 架构的详细探索
  • 用LangGraph实现聊天机器人记忆功能的深度解析
  • k8s搭建nfs共享存储
  • AI应用:电路板设计
  • Linux 线程概念与控制
  • Excel文件批量加密工具
  • Intellij Idea--解决Cannot download “https://start.spring.io‘: Connect timedout
  • 爬虫自动化:一文掌握 PyAutoGUI 的详细使用
  • Kruskal算法
  • 智能Agent场景实战指南 Day 23 : Agent安全与隐私保护
  • 百度前端面试题目整理
  • VUE进阶案例
  • 【C#学习Day13笔记】静态成员、接口、运算符重载和索引器
  • 小杰数据结构(one day)——心若安,便是晴天;心若乱,便是阴天。
  • python基础:request请求Cookie保持登录状态