unity数独游戏

2024-06-16 02:52
文章标签 游戏 unity 数独

本文主要是介绍unity数独游戏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class MainMenuPanel : MonoBehaviour
{public Button btnPlay; // 开始按钮public Slider sldDifficulty; // 难度滑动条private void Awake(){// 监听滑动条滑动事件sldDifficulty.onValueChanged.AddListener(OnSliderChange);// 开始按钮点击事件btnPlay.onClick.AddListener(OnPlayGame);}void Start(){// 启动的时候保存难度值SudokuGameManager.Instance.difficulty = (int)sldDifficulty.value;}public void OnSliderChange(float value){// 滑动条变化的时候保存难度值SudokuGameManager.Instance.difficulty = (int)sldDifficulty.value;}public void OnPlayGame(){// 调用游戏管理器中的方法来开始一局新的数独游戏SudokuGameManager.Instance.OnPlayNewGame();}
}

主要功能在该脚本中

在创建正确答案,扣除里面的数字并,把两个比较

重开游戏

算法用到了递归

using System.Collections.Generic;
using UnityEngine;public class SudokuBoard : MonoBehaviour
{// 正确答案int[,] gridNumber = new int[SudokuGameManager.girdLength, SudokuGameManager.girdLength];// 谜题int[,] puzzleNumber = new int[SudokuGameManager.girdLength, SudokuGameManager.girdLength];// 谜题备份,用于重开本局游戏int[,] puzzleBak = new int[SudokuGameManager.girdLength, SudokuGameManager.girdLength];public SudokuGrid grid;// 网格体public void Init(){// 创建一个有解的数独CreateGrid();// 根据已经创建的答案 来创建 谜题CreatePuzzle();// 根据谜题来初始化按钮InitButtons();}// 清理所有资源public void Clear(){// 清理谜题和答案数据gridNumber = new int[SudokuGameManager.girdLength, SudokuGameManager.girdLength];puzzleNumber = new int[SudokuGameManager.girdLength, SudokuGameManager.girdLength];puzzleBak = new int[SudokuGameManager.girdLength, SudokuGameManager.girdLength];}// 销毁某个物体下面的所有子物体void ClearChildren(Transform trans){for (int i = 0; i < trans.childCount; i++){Destroy(trans.GetChild(i).gameObject);}}// 某列是否包含某个数据bool ColumnContainsValue(int col, int value){for (int i = 0; i < SudokuGameManager.girdLength; i++){if (gridNumber[i, col] == value){return true;}}return false;}// 某一行是否包含某个数字bool RowContainsValue(int row, int value){for (int i = 0; i < SudokuGameManager.girdLength; i++){if (gridNumber[row, i] == value){return true;}}return false;}// 某一个子网格是否包含某个数字bool SquareContainsValue(int row, int col, int value){// 遍历子单元格(3X3)for (int i = 0; i < SudokuGameManager.subGirdLength; i++){for (int j = 0; j < SudokuGameManager.subGirdLength; j++){// 通过计算坐标 确定是属于哪个子网格if (gridNumber[(row / SudokuGameManager.subGirdLength) * SudokuGameManager.cellLength + i, (col / SudokuGameManager.subGirdLength) * SudokuGameManager.cellLength + j] == value){return true;}}}return false;}// 检查某个数是否已经存在于 横 列以及某个3X3的网格里bool CheckAll(int row, int col, int value){if (ColumnContainsValue(col, value)) // 列是否已经包含该数字{return false;}if (RowContainsValue(row, value)) // 行是否已经包含该数字{return false;}if (SquareContainsValue(row, col, value)) // 当前子九宫是否包含该数字{return false;}return true;}// 网格数字是否有效bool IsValid(){for (int i = 0; i < SudokuGameManager.girdLength; i++){for (int j = 0; j < SudokuGameManager.girdLength; j++){if (gridNumber[i, j] == 0){return false;}}}return true;}// 创建一个有效的数独网格void CreateGrid(){List<int> rowList = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };List<int> colList = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };// 先在00位置随机一个数据int value = rowList[Random.Range(0, rowList.Count)];gridNumber[0, 0] = value;rowList.Remove(value);colList.Remove(value);// 将其他8个数字随机到第一行中for (int i = 1; i < SudokuGameManager.girdLength; i++){value = rowList[Random.Range(0, rowList.Count)];gridNumber[i, 0] = value;rowList.Remove(value);}// 将其他几个数字随机到第一列中for (int i = 1; i < SudokuGameManager.girdLength; i++){value = colList[Random.Range(0, colList.Count)];// 需要判断是否会和第一个子网格有重复if (i < 3){while (SquareContainsValue(0, 0, value)){value = colList[Random.Range(0, colList.Count)]; // reroll}}gridNumber[0, i] = value;colList.Remove(value);}// 再随机对最后一个子网格添加三个合法的数字for (int i = 6; i < 9; i++){value = Random.Range(1, 10);while (SquareContainsValue(0, 8, value) || SquareContainsValue(8, 0, value) ||SquareContainsValue(8, 8, value)){value = Random.Range(1, 10);}gridNumber[i, i] = value;}// 先随机生成一个数独的底子,然后对它求解,解出的答案就是完整数独SolveSudoku();}// 对数独求解bool SolveSudoku(){int row = 0;int col = 0;// 如果已经生成完毕 就返回结果if (IsValid()){return true;}// 找到还没有生成数字的位置for (int i = 0; i < SudokuGameManager.girdLength; i++){for (int j = 0; j < SudokuGameManager.girdLength; j++){if (gridNumber[i, j] == 0){row = i;col = j;break;}}}// 循环 找到合适的数字,满足所有的规则for (int i = 1; i <= SudokuGameManager.girdLength; i++){if (CheckAll(row, col, i)){gridNumber[row, col] = i;// 递归找解 这里很重要,因为是对自身的递归,如果随机的数字正好全部都满足就结束了if (SolveSudoku()){return true;}else //如果某次递归找不到解 就会将该位置之 {gridNumber[row, col] = 0;}}}return false;}void CreatePuzzle(){// 根据事先完成的答案 创建谜题// 先将答案复制一份出来System.Array.Copy(gridNumber, puzzleNumber, gridNumber.Length);//移除数字,制造难度for (int i = 0; i < SudokuGameManager.Instance.difficulty; i++){int row = Random.Range(0, SudokuGameManager.girdLength);int col = Random.Range(0, SudokuGameManager.girdLength);// 循环随机,直到随到一个没有处理过的位置while (puzzleNumber[row, col] == 0){row = Random.Range(0, SudokuGameManager.girdLength);col = Random.Range(0, SudokuGameManager.girdLength);}puzzleNumber[row, col] = 0;}// 确保最少要出现8个不同的数字 才能保证唯一解List<int> onBoard = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };RandomizeList(onBoard);for (int i = 0; i < SudokuGameManager.girdLength; i++){for (int j = 0; j < SudokuGameManager.girdLength; j++){for (int k = 0; k < onBoard.Count - 1; k++){if (onBoard[k] == puzzleNumber[i, j]){onBoard.RemoveAt(k);}}}}// 如果剩余的数量大于1 说明没有8个不同的数字 那么就还原几个数字回来while (onBoard.Count - 1 > 1){int row = Random.Range(0, SudokuGameManager.girdLength);int col = Random.Range(0, SudokuGameManager.girdLength);if (gridNumber[row, col] == onBoard[0]){puzzleNumber[row, col] = gridNumber[row, col];onBoard.RemoveAt(0);}}// 将谜题备份用于重开本局游戏System.Array.Copy(puzzleNumber, puzzleBak, gridNumber.Length);}// 初始化可填写的按钮布局void InitButtons(){for (int i = 0; i < SudokuGameManager.girdLength; i++){for (int j = 0; j < SudokuGameManager.girdLength; j++){var cell = grid.GetCellByPosition(i,j);if (cell != null){cell.InitValues(puzzleNumber[i,j]);}}}}//重开本局游戏public void RestartGame(){System.Array.Copy(puzzleBak, puzzleNumber, gridNumber.Length);InitButtons();}// 打乱一个Listvoid RandomizeList(List<int> l){for (var i = 0; i < l.Count - 1; i++){// 随机交换两个位置int rand = Random.Range(i, l.Count);(l[i], l[rand]) = (l[rand], l[i]);}}// 将玩家输入更新到谜题中public void UpdatePuzzle(int row, int col, int value){puzzleNumber[row, col] = value;}/// <summary>/// 判定游戏是否完成/// </summary>/// <returns></returns>public bool CheckComplete(){// 检查填入的内容和谜底内容是否吻合for (int i = 0; i < SudokuGameManager.girdLength; i++){for (int j = 0; j < SudokuGameManager.girdLength; j++){if (puzzleNumber[i, j] != gridNumber[i, j]){return false;}}}return true;}}

using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;public class SudokuCell : MonoBehaviour
{public Vector2Int coordinate; // 在大网格里坐标public SudokuSubGrid subGrid;int value = 0; // 当前格子的值public TextMeshProUGUI txtNumber;// 数字控件public Button btnNum;// 按钮控件void Awake(){btnNum = GetComponent<Button>();txtNumber = GetComponentInChildren<TextMeshProUGUI>();btnNum.onClick.AddListener(ButtonClicked);}// 给网格设置数字public void InitValues(int value){// 初始化的时候,不为0表示该位置是系统提供的数字,否则就是玩家应该输入的数字if (value != 0){txtNumber.text = value.ToString();txtNumber.color = new Color32(119, 110, 101, 255);btnNum.enabled = false;}else{btnNum.enabled = true;txtNumber.text = " ";txtNumber.color = new Color32(0, 102, 187, 255);}}// 设置行列坐标public void SetCoordinate(int row, int col){coordinate = new Vector2Int(row, col);name = row.ToString() + col.ToString();}// 设置其归属的子网格public void SetSubGridParent(SudokuSubGrid sub){subGrid = sub;}/// <summary>/// 按钮事件/// 将当前的数字输入和指定的Cell进行绑定/// </summary>public void ButtonClicked(){SudokuGameManager.Instance.ActivateInputButton(this);}/// <summary>/// 更新单元格内的数字/// </summary>/// <param name="newValue"></param>public void UpdateValue(int newValue){value = newValue;if (value != 0){txtNumber.text = value.ToString();}else{txtNumber.text = "";}}
}

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;/// <summary>
/// 数独游戏的管理器
/// </summary>
public class SudokuGameManager : MonoBehaviour
{public static int girdLength = 9;// 网格的宽高public static int subGirdLength = 3;// 子网格的宽高// 子网格中 Cell的宽高public static int cellLength = SudokuGameManager.girdLength / SudokuGameManager.subGirdLength;public SudokuCell SudokuCell_Prefab; // 单元格的预制体// get; private set; 的写法是一种语法糖,表示这个值别的类可以读取和使用,但只有自己才能设置它public static SudokuGameManager Instance { get; private set; }public MainMenuPanel mainMenu;// 主界面相关逻辑public SudokuPlayPanel sudokuPlay; // 数独的游戏界面// 按照9X9的格子来算,一共是81个有效数字,如果已知的数字越多,那么未知的数字就越好推导// 所以难度的表达方式就是,设定一个数字,在数独创建完成之后,隐藏掉这些数字来增加难度public int difficulty = 20; // 默认的难度值public Image ipButtonsPanel; // 游戏输入按钮public List<Button>btnNums = new List<Button>(); // 数字输入// 记录上一次点击的格子 以便数字进行输入SudokuCell lastCell;private void Awake(){//单例模式Instance = this;for (int i = 0; i < btnNums.Count; i++){// 需要将i的地址传递出来 int index = i;// 为当前遍历到的按钮添加点击监听器// 当按钮被点击时,调用OnNumBtnClicked方法,并将index(即按钮的索引)作为参数传递btnNums[i].onClick.AddListener(delegate(){ OnNumBtnClicked(index);});}}private void Start(){// 程序启动的时候,默认显示开始界面OnBackToMenu();}// 返回到开始菜单public void OnBackToMenu(){// 程序启动的时候,默认显示开始界面mainMenu.gameObject.SetActive(true);sudokuPlay.gameObject.SetActive(false);// 执行游戏清理sudokuPlay.Clear();}// 开始游戏public void OnPlayNewGame(){// 隐藏开始界面 显示游戏界面mainMenu.gameObject.SetActive(false);sudokuPlay.gameObject.SetActive(true);// 隐藏数字输入面板ipButtonsPanel.gameObject.SetActive(false);// 执行游戏初始化sudokuPlay.Init();}/// <summary>/// 将当前的数字输入和指定的Cell进行绑定/// </summary>/// <param name="cell"></param>public void ActivateInputButton(SudokuCell cell){ipButtonsPanel.gameObject.SetActive(true);lastCell = cell;}/// <summary>/// 点击了某个数字按钮/// </summary>/// <param name="num"></param>public void OnNumBtnClicked(int num){// 更新上一次选中的格子的数值为当前被点击的数字按钮的值lastCell.UpdateValue(num);// 在数独游戏的逻辑板上更新相应的格子数值,使用lastCell的坐标和被点击的数字sudokuPlay.board.UpdatePuzzle(lastCell.coordinate.x, lastCell.coordinate.y, num);// 隐藏数字输入面板ipButtonsPanel.gameObject.SetActive(false);}}

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 数独的大网格
/// </summary>
public class SudokuGrid : MonoBehaviour
{// 所有的子网格 需要处理成二维数组public SudokuSubGrid[,] subGrids { get; private set; }// 子网格public SudokuCell[] cells;// 所有的单元格void Awake(){// 获取所有子网格体var grid = GetComponentsInChildren<SudokuSubGrid>();// 建立子网格的二维数组subGrids = new SudokuSubGrid[SudokuGameManager.subGirdLength, SudokuGameManager.subGirdLength];// 通过循环将二维数组分配到指定位置int index = 0;for (int i = 0; i < SudokuGameManager.subGirdLength; i++){for (int j = 0; j < SudokuGameManager.subGirdLength; j++){subGrids[i, j] = grid[index++];subGrids[i, j].SetCoordinate(i,j);// 设置坐标subGrids[i, j].InitCells();// 初始化网格}}cells = GetComponentsInChildren<SudokuCell>();}/// <summary>/// 根据坐标获取Cell/// </summary>/// <param name="row"></param>/// <param name="col"></param>/// <returns></returns>public SudokuCell GetCellByPosition(int row,int col){foreach (var cell in cells){if (cell.coordinate.x == row && cell.coordinate.y == col){return cell;}}return null;}}

using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.PlayerLoop;
using UnityEngine.Serialization;
using UnityEngine.UI;public class SudokuPlayPanel : MonoBehaviour
{public Button btnBackToMenu;// 返回主界面按钮public Button btnBackToMenuInWinPanel;// 获胜面板上的返回主界面按钮public Button btnNewLevel;// 新建一个关卡public Button btnReplay; // 重新开始本次关卡public Button btnComplete; // 完成关卡public TextMeshProUGUI txtWrongTips; // 结果错误提示public Image imgWinPanel; // 获胜界面public TextMeshProUGUI txtTimer;// 计时器float levelStartTime = 0f; // 关卡开始的时间,用于计时器的计算public SudokuBoard board;// 游戏核心逻辑private void Awake(){// 返回主菜单btnBackToMenu.onClick.AddListener(OnBtnBackToMenuClicked);btnBackToMenuInWinPanel.onClick.AddListener(OnBtnBackToMenuClicked);// 新建关卡btnNewLevel.onClick.AddListener(OnBtnNewClicked);// 重新开始本关卡btnReplay.onClick.AddListener(OnbtnReplayClicked);// 完成关卡btnComplete.onClick.AddListener(OnbtnCompleteClicked);}private void Update(){// 计时器CountTimer();}/// <summary>/// 初始化游戏/// </summary>public void Init(){// 隐藏错误提示txtWrongTips.gameObject.SetActive(false);// 隐藏获胜面板imgWinPanel.gameObject.SetActive(false);// 记录当前的时间戳levelStartTime = Time.realtimeSinceStartup;// 核心逻辑初始化board.Init();}public void Clear(){levelStartTime = 0;// 清除计时器开始时间// 核心逻辑清理board.Clear();}/// <summary>/// 计时器逻辑/// </summary>void CountTimer(){float t = Time.realtimeSinceStartup - levelStartTime;int seconds = (int)(t % 60);t /= 60;int minutes = (int)(t % 60);txtTimer.text = string.Format("{0}:{1}", minutes.ToString("00"), seconds.ToString("00"));}/// <summary>/// 返回主菜单/// </summary>public void OnBtnBackToMenuClicked(){// 清理游戏Clear();// 返回主菜单SudokuGameManager.Instance.OnBackToMenu();}/// <summary>/// 开始新关卡/// </summary>public void OnBtnNewClicked(){// 先清理再初始化Clear();Init();}/// <summary>/// 重玩本关卡/// </summary>public void OnbtnReplayClicked(){// 调用核心逻辑的重玩本局board.RestartGame();}/// <summary>/// 完成游戏/// </summary>public void OnbtnCompleteClicked(){// 检查是否完成游戏if (board.CheckComplete()){imgWinPanel.gameObject.SetActive(true);}else{txtWrongTips.gameObject.SetActive(true);// 3秒后 错误提示消失StartCoroutine(HideWrongText());}}IEnumerator HideWrongText(){yield return new WaitForSeconds(3.0f);txtWrongTips.gameObject.SetActive(false);}}

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;/// <summary>
/// 大网格下的小网格
/// </summary>
public class SudokuSubGrid : MonoBehaviour
{public Vector2Int coordinate; //子网格所属的坐标public SudokuCell[,] cells { get; private set; }// 创建所属的单元格private void Awake(){cells = new SudokuCell[SudokuGameManager.cellLength, SudokuGameManager.cellLength];}// 设置行列坐标public void SetCoordinate(int row, int col){coordinate = new Vector2Int(row, col);}// 初始化网格public void InitCells(){for (int i = 0; i < SudokuGameManager.cellLength; i++){for (int j = 0; j < SudokuGameManager.cellLength; j++){cells[i,j] = Instantiate(SudokuGameManager.Instance.SudokuCell_Prefab,transform);cells[i,j].SetCoordinate(coordinate.x * SudokuGameManager.cellLength + i,coordinate.y * SudokuGameManager.cellLength +j);cells[i,j].SetSubGridParent(this);cells[i,j].InitValues(1);}}}}

这篇关于unity数独游戏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1065298

相关文章

国产游戏崛起:技术革新与文化自信的双重推动

近年来,国产游戏行业发展迅猛,技术水平和作品质量均得到了显著提升。特别是以《黑神话:悟空》为代表的一系列优秀作品,成功打破了过去中国游戏市场以手游和网游为主的局限,向全球玩家展示了中国在单机游戏领域的实力与潜力。随着中国开发者在画面渲染、物理引擎、AI 技术和服务器架构等方面取得了显著进展,国产游戏正逐步赢得国际市场的认可。然而,面对全球游戏行业的激烈竞争,国产游戏技术依然面临诸多挑战,未来的

火柴游戏java版

代码 /*** 火柴游戏* <p>* <li>有24根火柴</li>* <li>组成 A + B = C 等式</li>* <li>总共有多少种适合方式?</li>* <br>* <h>分析:</h>* <li>除去"+"、"="四根,最多可用火柴根数20根。</li>* <li>全部用两根组合成"1",最大数值为1111。使用枚举法,A和B范围在0~1111,C为A+B。判断</li>** @

国产游戏行业的崛起与挑战:技术创新引领未来

国产游戏行业的崛起与挑战:技术创新引领未来 近年来,国产游戏行业蓬勃发展,技术水平不断提升,许多优秀作品在国际市场上崭露头角。从画面渲染到物理引擎,从AI技术到服务器架构,国产游戏已实现质的飞跃。然而,面对全球游戏市场的激烈竞争,国产游戏技术仍然面临诸多挑战。本文将探讨这些挑战,并展望未来的机遇,深入分析IT技术的创新将如何推动行业发展。 国产游戏技术现状 国产游戏在画面渲染、物理引擎、AI

第四次北漂----挣个独立游戏的素材钱

第四次北漂,在智联招聘上,有个小公司主动和我联系。面试了下,决定入职了,osg/osgearth的。月薪两万一。 大跌眼镜的是,我入职后,第一天的工作内容就是接手他的工作,三天后他就离职了。 我之所以考虑入职,是因为 1,该公司有恒歌科技的freex平台源码,可以学学,对以前不懂的解解惑。 2,挣点素材钱,看看张亮002的视频,他用了6000多,在虚幻商城买的吸血鬼游戏相关的素材,可以玩两年。我

Unity Post Process Unity后处理学习日志

Unity Post Process Unity后处理学习日志 在现代游戏开发中,后处理(Post Processing)技术已经成为提升游戏画面质量的关键工具。Unity的后处理栈(Post Processing Stack)是一个强大的插件,它允许开发者为游戏场景添加各种视觉效果,如景深、色彩校正、辉光、模糊等。这些效果不仅能够增强游戏的视觉吸引力,还能帮助传达特定的情感和氛围。 文档

nyoj 1038 纸牌游戏

poj 的一道改编题,说是翻译题更恰当,因为只是小幅度改动。 一道模拟题,代码掌控能力比较好,思维逻辑清晰的话就能AC。 代码如下: #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;struct node{char c[5];int rk;char da[5];int nu

如果出一个名叫白神话悟空的游戏

最近黑神话由于与原著不符引起了原著派的争议。 所以我在摸鱼的时候想到如果游科或者某个别的公司“痛改前非”不夹带私货完全复刻吴承恩百回版剧情制作一个“重走西游路”的游戏,会有一个什么样的销量?(设定为原著派已经多方渠道认证,此游戏的确没有夹带私货,绝大部分复刻了原著剧情) 游戏玩法我想了几类 超长线性有岔路蜈蚣形状地图,蜈蚣的腿部是探索区域和支线,重走西游路线,开篇就是开始取经前唐玄宗御弟cg

Unity协程搭配队列开发Tips弹窗模块

概述 在Unity游戏开发过程中,提示系统是提升用户体验的重要组成部分。一个设计良好的提示窗口不仅能及时传达信息给玩家,还应当做到不干扰游戏流程。本文将探讨如何使用Unity的协程(Coroutine)配合队列(Queue)数据结构来构建一个高效且可扩展的Tips弹窗模块。 技术模块介绍 1. Unity协程(Coroutines) 协程是Unity中的一种特殊函数类型,允许异步操作的实现

Unity 资源 之 Super Confetti FX:点亮项目的璀璨粒子之光

Unity 资源 之 Super Confetti FX:点亮项目的璀璨粒子之光 一,前言二,资源包内容三,免费获取资源包 一,前言 在创意的世界里,每一个细节都能决定一个项目的独特魅力。今天,要向大家介绍一款令人惊艳的粒子效果包 ——Super Confetti FX。 二,资源包内容 💥充满活力与动态,是 Super Confetti FX 最显著的标签。它宛如一位

Unity数据持久化 之 一个通过2进制读取Excel并存储的轮子(4)

本文仅作笔记学习和分享,不用做任何商业用途 本文包括但不限于unity官方手册,unity唐老狮等教程知识,如有不足还请斧正​​ Unity数据持久化 之 一个通过2进制读取Excel并存储的轮子(3)-CSDN博客  这节就是真正的存储数据了   理清一下思路: 1.存储路径并检查 //2进制文件类存储private static string Data_Binary_Pa