// перекрасить ячейки победившей линии в победные ячейки private void ReColorCellsPobeda(OneHit point, int whoHited, short line) { point.SetStateWin(line); Point curPoint = point.coord.GetAround(line); OneHit curPointOH = FindPoint(curPoint); short i = 0; for (; curPointOH.state == whoHited; i++) { curPointOH.SetStateWin(line); curPoint = curPoint.GetAround(line); curPointOH = FindPoint(curPoint); } // 0:3 1:4 2:5 3:6 4:1 5:2 line = (short)((line + 3) % 6); curPoint = point.coord.GetAround(line); curPointOH = FindPoint(curPoint); i = 0; for (; curPointOH.state == whoHited; i++) { curPointOH.SetStateWin(line); curPoint = curPoint.GetAround(line); curPointOH = FindPoint(curPoint); } }
public void CreateBombHill(List <OneHit> loh) { for (int i = 0; i < loh.Count; i++) { OneHit oh = loh[i]; if (oh.coord.RingNum() < 3) { //oh.damageHill = 0; continue; } float rnd = UnityEngine.Random.value; if (rnd < gm.likenessBomb[0]) { // выпала бомба oh.CreateBomb(); continue; } rnd = UnityEngine.Random.value; if (rnd < gm.likenessHill[0]) { // выпала аптечка oh.CreateHill(); continue; } //oh.damageHill = 0; } }
// совершить ход в данную точку. Финальная - завершительная часть хода. public virtual bool MakeHit(OneHit point, int player) { //player: 1 2 3 // проверить занята ли точка, либо случилась победа if (point.state != 0 || gm.win == true) { return(false); } // Обновить точку, выше всех остальных шагов чтобы пользователь видел что произошёл ход point.SetState(player); // В последнюю схоженную данным игроком ячейку помещаем "иконку последнего хода" этого игрока lastHitedPoint[player - 1].transform.position = point.transform.position; if (FindPobedaInPoint(point.coord, player)) { return(true); } // создать чёрное поле AddBlackField(point.coord); UnityEngine.Debug.Log(string.Format("{0}", points.Count)); return(true); }
// совершить ход в данную точку. Финальная - завершительная часть хода. public bool MakeHit(OneHit point, int player) { //player: 1 2 3 // проверить занята ли точка, либо случилась победа if (point.state != 1) { return(false); } point.whoShodil = player; // Обновить точку, выше всех остальных шагов чтобы пользователь видел что произошёл ход // 1:2 2:3 3:4 point.SetState(player + 1); // В последнюю схоженную данным игроком ячейку помещаем "иконку последнего хода" этого игрока lastHitedPoints[player - 1] = point.gameObject; //if (FindPobedaInPoint(point.coord, player)) //{ //return true; //} // создать чёрное поле AddBlackField(point.coord); return(true); }
public int blackCells; // толщина пустых ячеек вокруг занятых private void Start() { int orientation = LocalDB._def_GexagonsOrientation; // если ориентация камеры вертикальная - поворачиваем текст в ячейке на 30 градусов if (orientation == 1) { mainCell.GetComponent <OneHit>().GetCountBombsObject().transform.Rotate(Vector3.forward, 30); mainCell.GetComponent <OneHit>().GetBombMarkHillObject().transform.Rotate(Vector3.forward, 30); } OneHit.grd = this; BoCoCell.grd = this; points = new Dictionary <string, OneHit>(); // Создаём новую точку в 000 координатах и получаем её объект на сцене Point zeroPoint = new Point(0, 0); OneHit newCellElem = NewCell(zeroPoint); // заполняем полупрозрачное поле AddBlackField(zeroPoint); // открываем поле OpenField(newCellElem); // открываем ячейки OnStart(); }
// Найдём же победу в данной точке private bool FindPobedaInPoint(Point point, int whoHited) { List <short> countPointsWhoHitedInSubLine = new List <short>(); // отдельно рассмотрим каждое направление for (short line = 0; line < 6; line++) { Point curPoint = point.GetAround(line); OneHit curPointOH = FindPoint(curPoint); short i = 0; // такая ситуация может появиться если ход был на границе if (curPointOH != null) { for (; curPointOH.state == whoHited; i++) { curPoint = curPoint.GetAround(line); curPointOH = FindPoint(curPoint); } } countPointsWhoHitedInSubLine.Add(i); if (line >= 3) { if (countPointsWhoHitedInSubLine[line - 3] + countPointsWhoHitedInSubLine[line] + 1 >= winCells) { gm.DeclarePobeda(point, whoHited); ReColorCellsPobeda(FindPoint(point), whoHited, line); return(true); } } } return(false); }
/* добавить в данную субточку точку(p), в которую только что сходили, для учёта веса * гарантируется, что p действительно даходится на subline, * так же гарантируется, что расстояние между p и текущей точкой действительно равно dist * и что если данная функция вызывается, значит точку действительно надо добавить */ public void PushPoint(OneHit p, int subLine, short dist) { pointsInLine[subLine].Add(p); if (dist > nearestPointInLine[subLine]) { nearestPointInLine[subLine] = dist; } }
// открывает поле при клике в данную точку public int OpenField(OneHit p, bool needCountAroundBombs = true) { /*for (int i = 0; i < 6; i++) * if ( FindPoint( p.coord.GetAround(i) ).damageHill==2 ) * FindPoint( p.coord.GetAround(i) ).GetBombObject().SetActive(true);*/ // если ячейки не существует, если она уже открыта или если закрыта // если точка была помечена как бомба - убираем пометку if (p == null || p.damageHill == 2 || p.state != 1 || p.playerMarkBomb == 1) { return(0); } for (int i = 0; i < 6; i++) { // Вокруг отустствуeт одна или более точек - текущую не показываем if (!FindPoint(p.coord.GetAround(i))) { return(0); } } p.SetState(2); // Сколько бомб вокруг точки int countBombs = 0; for (int i = 0; i < 6; i++) { OneHit oh = FindPoint(p.coord.GetAround(i)); if (oh.damageHill == 2 || oh.damageHill == 4) { countBombs++; } } // если вокруг есть таблетки - показываем их p.CheckHill(); // показываем сколько вокруг бомб if (countBombs > 0 && p.damageHill != 4) { p.DrawAroundBombs(countBombs); return(1); } // считаем количество открытых точек int ret = 0; for (int i = 0; i < 6; i++) { ret += OpenField(FindPoint(p.coord.GetAround(i))); } return(ret); }
/* * Если ходет живой чел за данным телефоном - вызывается MakeHitLocalPlayer, * если ходит бот или чувак по интернетику - GetHit * после всех этих действий вызывается UpdateAllAfterHit для обновления префабов, вызовов реанализаторов ботов и прочего. * * После хода живого чела бесконечной рекурсией вызывается GetHit, где ходит бот или интернет чувак, в зависимости от того что в orderHits[i] обозначено как null, * рекурсия разравается когда должен ходить локальный игрок * UpdateAllAfterHit() вызывается после каждого хода. * */ // Это работает для всех режимов игры. и мультиплеер и против ботов. Локальный игрок - это тот кто может ходить с устройства и не является ботом. public void MakeHitLocalPlayer(OneHit p) { if (!MakeHit(p, playerCurHit + 1)) { return; } UpdateAllAfterHit(p); GetHit(); }
public OneHit NewPoint(Point point) { GameObject newEl = Instantiate(mainCell, point.GetCoord2D(), Quaternion.identity); newEl.name = point.ToString(); newEl.transform.SetParent(pointsList.transform); OneHit ohp = newEl.GetComponent <OneHit>(); ohp.Initialize(point); points.Add(newEl.name, ohp); return(newEl.GetComponent <OneHit>()); }
public void UpdateAllAfterHit(OneHit p) { // Боты перерасчитывают свои веса for (int i = 0; i < countBots; i++) { //bcs[i].ReanalyseAfterHit(p); } // Определяем кто ходит // playerCurHit:playerCurHit 0:1 1:2 2:0 или 0:1 1:0 playerCurHit = (playerCurHit + 1) % countPlayers; // в камере меняем иконку игрока который ходит cam.UpdateImgPlayerCurHit(); }
// Анализируем ход в текущую точку, не важно чей, функция сама определит public void ReanalyseAfterHit(OneHit start) { // Чья точка в данной клетке (true - значит игрока, то есть моя) bool iBot = (myColor == start.state); for (short subLine = 0; subLine < 6; subLine++) { short subLineRever = ReverseLine(subLine); // была ли на subLine обнаружена точка цвет которой отличается от цвета start (враг для start) bool wasEnemyPoint = false; // была ли обнаружена какая либо точка bool wasPoint = false; // Текущая субточка Point curPoint = start.coord.GetAround(subLine); for (short i = 0; i < maxCheckedLine; i++) { OneHit curPointOH = gm.grd.FindPoint(curPoint); BoCoCell curPointBK = null;// curPointOH.bcc; curPointBK.CheckInitialize(); if (curPointBK.WhoLeaderInSubLine(subLineRever) != start.state) { curPointBK.DestroySubLine(subLineRever); } if (!wasEnemyPoint) { if (curPointOH.whoShodil != 0 && curPointOH.whoShodil != start.whoShodil) { wasEnemyPoint = true; } else { // добавляем свои субточки для добавленной точки (сделанный ход) curPointBK.PushPoint(start, subLineRever, i); } } curPointBK.ReCountScore(); // Текущая субточка curPoint = curPoint.GetAround(subLine); } } }
// совершить ход в данную точку. Финальная - завершительная часть хода. public bool MakeHit(OneHit point, int player) { //player: 1 2 3 // проверяем можно ли сюда ходить if (point.state != 1 && point.state != 2 || point.playerMarkBomb != 0) { return(false); } if (point.state == 1) { int i = 0; for (; i < 6; i++) { OneHit oh = FindPoint(point.coord.GetAround(i)); if (oh && oh.state > 1) { break; } } if (i == 6) { return(false); } } int res = point.MakeHit(player); if (res == 1) { gm.UpdateHill(); } else if (res == 2) { gm.UpdateDamage(); } // создать чёрное поле AddBlackField(point.coord); // открываем ячейки, добавляем их количество к текущему юзеру gm.players[player - 1].CountOpenCellsAdd(OpenField(point, res != 2)); return(true); }
public int blackCells; // толщина пустых ячеек вокруг занятых private void Start() { OneHit.grd = this; BoCoCell.grd = this; points = new Dictionary <string, OneHit>(); // 2:5 3:4 winCells = 7 - LocalDB._def_CountPlayers; // Создаём новую точку в 000 координатах и получаем её объект на сцене Point zeroPoint = new Point(0, 0); OneHit newCellElem = NewCell(zeroPoint); // заполняем полупрозрачное поле AddBlackField(zeroPoint); OnStart(); }
/* * Для каждой добавленной ячейки проверяем существуют ли 3 рядом стоящие точки в списке точек * если да - добавляем ребро, иначе - кладём болт * */ private void AddBlackField(Point point) { for (int x = -blackCells; x <= blackCells; x++) { for (int y = -blackCells; y <= blackCells; y++) { // чтобы получался красивый шестиугольник из тыщи точег if (Math.Abs(x - y) > blackCells) { continue; } Point newPoint = new Point(point.x + x, point.y + y); // если текущая точка не центр ячейки и если точки не существует if (newPoint.GetSystCoordOrientation() != 2 && FindPoint(newPoint) == null) { OneHit oh = NewPoint(newPoint), ch; // проверяем наличие рядомстоящих точек и добавляем рёбра ch = FindPoint(newPoint.GetAround(1)); if (ch != null) { NewEdge(oh, ch); } ch = FindPoint(newPoint.GetAround(5)); if (ch != null) { NewEdge(oh, ch); } ch = FindPoint(newPoint.GetAround(9)); if (ch != null) { NewEdge(oh, ch); } } } } }
public GameObject NewEdge(OneHit p1, OneHit p2) { Vector3 edgeVector = p2.transform.position - p1.transform.position; // находим угол через скалярное произведение вектора оси координат х и edgeVector // когда так и не вкурил кватернионы(((((((((((((((((((((((((( float cosa = edgeVector.x / edgeVector.magnitude, signAsina = Mathf.Asin(edgeVector.y / edgeVector.magnitude) > 0 ? 1 : -1, degree = 180f / Mathf.PI * signAsina * Mathf.Acos(edgeVector.x / edgeVector.magnitude); Vector3 edgePosition = edgeVector / 2 + p1.transform.position; GameObject newEdge = Instantiate(mainEdge, edgePosition, Quaternion.Euler(0, 0, degree)); newEdge.name = p1.coord.ToString() + "^" + p2.coord.ToString(); newEdge.transform.SetParent(edgesList.transform); edges.Add(newEdge.name, newEdge); return(newEdge); }
public override bool MakeHit(MainInGame.OneHit point, int player) { if (point.state != 0 || gm.win == true) { return(false); } // Если сходил синий - необходимо инкриментировать количество ходов if (((GameManager)gm).playerCurHit == 0) { ((GameManager)gm).hits++; // согласен, забавная конструкция, но если её убрать, он будет брать GameManager из MainInGame, а не из GameInHits ((CameraScr)gm.cam).CountHitsView(); } if (!base.MakeHit(point, player)) { return(false); } return(true); }
// Обновить последнюю хилку/урон полученный игроком public void GetTableParamsPlayers(int player, bool isBomb, string txt) { lastHillDamageTxt.text = txt; GameObject imgBombHill = isBomb ? lastDamageImg : lastHillImg; if (isBomb) { imgBombHill = lastDamageImg; lastDamageImg.SetActive(true); lastHillImg.SetActive(false); } else { imgBombHill = lastDamageImg; lastHillImg.SetActive(true); lastDamageImg.SetActive(false); } imgBombHill.GetComponent <Image>().color = OneHit.GetPlayerColor(player); lastHillDamageTxt.color = OneHit.GetPlayerColor(player); }
public void UpdateAllAfterHit(OneHit p) { // меняем позицию игрока p.SetState(players[playerCurHit].p.state); players[playerCurHit].p.SetState(2); players[playerCurHit].p = p; for (int i = 0; i < countPlayers; i++) { // Боты перерасчитывают свои веса if (players[i].GetType() == typeof(Bot)) { ((Bot)players[i]).ReanalyseAfterHit(p); } } // Определяем кто ходит int pch = playerCurHit; //игрок который только что ходил do { // playerCurHit:playerCurHit 0:1 1:2 2:0 или 0:1 1:0 playerCurHit = (playerCurHit + 1) % countPlayers; } // пропускаем всех мёртвых игроков, они больше не ходят while (playerCurHit != pch && players[playerCurHit].playerDead); if (playerCurHit == pch && players[playerCurHit].playerDead) {// все умерли - конец игры gameOver = true; cam.GameOverDeclare(pch); return; } // в камере меняем иконку игрока который ходит cam.UpdateImgPlayerCurHit(); }
public virtual bool MakeHit(OneHit point, int player) { return(grd.MakeHit(point, player)); }
public void ReanalyseAfterHit(OneHit p) { }
public virtual bool MakeHit(OneHit point, int player) { return((gameOver) ? false : grd.MakeHit(point, player)); }