基础tips之前博文有。
题目:
思路:
这其实是个博弈论的问题,谁先手谁后手,数组为偶数个还是奇数个都是决定胜负的关键,但我们的目标还是那句话,只需要达到将算法过程变成更好理解的方式,也就是说假设你是Alice并且先手,然后当你擦掉数字之后,另一个人选的时候,异或运算得出的结果是0,看到0的这个人就欣喜的胜利了,也就是winner,抓住这点,我们就可以开始做了。
“原力与你同在”。
效果图:
Alice获胜:
Bob获胜:
?全部擦掉后Alice获胜:
源代码:
XorGame类
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class XorGame : MonoBehaviour
{
public string Text;//文本
public int index;//射线检测到的gameobject的名字
public GameObject Bob;//Bob行动人
public GameObject Alice;//Alice行动人
public void Start()
{
NumsManager.instance.CreateRandomValue();//单例引用创建随机数方法
NumsManager.instance.CaculateXorAllValue();//单例引用所有数字异或运算方法
NumsManager.MoveNum = 0;
}
public void Update()
{
DestroyNum();
//根据列表中的数改变文本
for (int i = 0; i < NumsManager.Xor.Count; i++)
{
switch (i)
{
case 0:
ChangeText(0, "0");
break;
case 1:
ChangeText(1, "1");
break;
case 2:
ChangeText(2, "2");
break;
case 3:
ChangeText(3, "3");
break;
case 4:
ChangeText(4, "4");
break;
case 5:
ChangeText(5, "5");
break;
case 6:
ChangeText(6, "6");
break;
case 7:
ChangeText(7, "7");
break;
case 8:
ChangeText(8, "8");
break;
case 9:
ChangeText(9, "9");
break;
}
}
//判断Alice还是Bob行动回合,并且默认为Alice先手(可修改)
if (NumsManager.MoveNum == 0|| NumsManager.MoveNum==2|| NumsManager.MoveNum == 4|| NumsManager.MoveNum == 6|| NumsManager.MoveNum == 8|| NumsManager.MoveNum == 10)
{
Alice.gameObject.SetActive(true);
Bob.gameObject.SetActive(false);
}
else if(NumsManager.MoveNum == 1 || NumsManager.MoveNum == 3|| NumsManager.MoveNum == 5|| NumsManager.MoveNum == 7|| NumsManager.MoveNum == 9)
{
Alice.gameObject.SetActive(false);
Bob.gameObject.SetActive(true);
}
}
/// <summary>
/// 改变文本
/// </summary>
/// <param name="index"></param>
/// <param name="name"></param>
void ChangeText(int index,string name)
{
Text = NumsManager.Xor[index].ToString();
GameObject.Find(name).GetComponent<TextMesh>().text = Text;
}
/// <summary>
/// Alice擦掉数字(射线检测)
/// </summary>
void DestroyNum()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray,out hit))
{
index = Convert.ToInt32(hit.collider.name);
if (Input.GetMouseButtonDown(0)&& hit.collider.name!=null)
{
NumsManager.MoveNum++;
Destroy(hit.transform.gameObject);
NumsManager.Xor.RemoveAt(index);
NumsManager.instance.CaculateXorAllValue();
}
}
}
}
?NumsManager类(单例模式)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class NumsManager : MonoBehaviour
{
public static NumsManager instance;
public static int num;//随机数
public static int MoveNum;
public static List<int> Xor = new List<int>();
public int Value;//当前所有数字异或的结果(整型)
public Text Sum;//当前所有数字异或的结果(unity文本)
public GameObject BobWin;//Bob获胜预制体
public GameObject AliceWin;//Alice获胜预制体
//单例模式
NumsManager()
{
instance = this;
}
public void Awake()
{
Xor = new List<int>(10);//列表存储随机数
}
public void Update()
{
Sum.text = Value.ToString();//当前所有数字异或的结果(字符型)
WinOrLose();
//如果只剩一个数字,按位异或运算得到它本身
if (Xor.Count == 1)
{
Value = Xor[0];
}
//如果无数字剩余,按位异或运算结果为 0
if (Xor.Count == 0)
{
Value = 0;
}
}
/// <summary>
/// 创建随机数
/// </summary>
public void CreateRandomValue()
{
for (int i = 0; i < 10; i++)
{
num = Random.Range(0, 9);
Xor.Add(num);
}
}
/// <summary>
/// 异或运算
/// </summary>
/// <param name="XorA"></param>
/// <param name="XorB"></param>
public void CaculateXorValue(int XorA, int XorB)
{
Value = XorA ^ XorB;
}
/// <summary>
/// 所有数字异或运算
/// </summary>
public void CaculateXorAllValue()
{
CaculateXorValue(Xor[0], Xor[1]);
for (int i = 0; i < Xor.Count; i++)
{
CaculateXorValue(Value, Xor[i+2]);
}
}
/// <summary>
/// 判断谁胜利
/// </summary>
public void WinOrLose()
{
if ((MoveNum == 0 && Value == 0) || (MoveNum == 2 && Value == 0) || (MoveNum == 4 && Value == 0) || (MoveNum == 6 && Value == 0) || (MoveNum == 8 && Value == 0) || (MoveNum == 10 && Value == 0))
{
AliceWin.gameObject.SetActive(true);//Alice获胜
}
else if ((MoveNum == 1 && Value == 0) || (MoveNum == 3 && Value == 0) || (MoveNum == 5 && Value == 0) || (MoveNum == 7 && Value == 0) || (MoveNum == 9 && Value == 0))
{
BobWin.gameObject.SetActive(true);//Bob获胜
}
}
}
还有一个处理开始按钮监听的类,太过简单了就不贴了,就是SceneManager.LoadScene这个方法解决游戏开始功能。
项目部分截图:
由于是粗制,项目还有些Bug待修改,但是博主最近忙毕设,就没空改了,感兴趣的大佬或者萌新可以下方留言,看到了我就会回复,回复的不是很迅速还请见谅。
|