chip-game/Assets/Scripts/FieldModel.cs
2026-01-12 09:36:17 +03:00

315 lines
9.7 KiB
C#

using System;
using UnityEngine;
//using static UnityEngine.Rendering.DebugUI.Table;
//êåì çàíÿò/íå çàíÿò ñëîò
public enum CellState
{
Empty, Player1, Player2
}
public class FieldModel
{
//äâóìåðíûé ìàññèâ äëÿ ïîëÿ
public CellState[,] fieldArr;
public int height, width;
// Êåøèðîâàííûå ìàññèâû äëÿ èçáåæàíèÿ àëëîêàöèé
private static readonly int[] tempIndexesRow = new int[4];
private static readonly int[] tempIndexesColumn = new int[4];
public FieldModel(int width, int height)
{
//0 èíäåêñ äëÿ ñòðîê, 1 èíäåêñ äëÿ ñòîëáöîâ
this.width = width;
this.height = height;
makeEmptyField(width, height);
}
public void makeEmptyField(int width, int height)
{
fieldArr = new CellState[height, width];
Array.Clear(fieldArr, 0, fieldArr.Length);
//for (int row = 0; row < height; row++)
//{
// for (int col = 0; col < width; col++)
// {
// fieldArr[row, col] = CellState.Empty;
// }
//}
}
//Îñíîâíûå ïðîâåðêè ñ ðàçâåðíóòûì ðåçóëüòàòîì
public CheckResult check(int row, int col)
{
CheckResult result;
result = checkRow(row);
if (result.end) return result;
result = checkColumn(col);
if (result.end) return result;
result = checkDiagonalDownUp(row, col);
if (result.end) return result;
result = checkDiagonalUpDown(row, col);
if (result.end) return result;
if (checkDraw())
{
return new CheckResult(true, true);
}
return result;
}
public CheckResult checkRow(int row)
{
CellState currentPlayer = GameManager.instance.currentPlayer;
int lineLength = 0;
for (int col = 0; col < 7; col++)
{
CellState cell = fieldArr[row, col];
if (cell != currentPlayer)
{
lineLength = 0;
continue;
}
lineLength++;
if (lineLength == 4)//íàøëè ðÿä èç 4 ôèøåê
{
//ìàññèâû ÷òîáû çàïîìíèòü èç-çà êàêîé êîìáèíàöèè ïðîèçîøëà ïîáåäà
//int[] indexesRow = new int[4];
//int[] indexesColumn = new int[4];
for (int i = 0; i < 4; i++)
{
//indexesColumn[i] = col - i;
//indexesRow[i] = row;
tempIndexesColumn[i] = col - i;
tempIndexesRow[i] = row;
}
return new CheckResult(true, false, tempIndexesRow, tempIndexesColumn);
}
}
return new CheckResult(false, false);//íå íàøëè êîìáèíàöèþ
}
public CheckResult checkColumn(int column)
{
CellState currentPlayer = GameManager.instance.currentPlayer;
int lineLength = 0;
for (int row = 5; row >= 0; row--)
{
CellState cell = fieldArr[row, column];
if (cell != currentPlayer)
{
lineLength = 0;
continue;
}
lineLength++;
if (lineLength == 4)//íàøëè ðÿä èç 4 ôèøåê
{
//int[] indexesRow = new int[4];
//int[] indexesColumn = new int[4];
for (int i = 0; i < 4; i++)
{
//indexesColumn[i] = column;
//indexesRow[i] = row + i;
tempIndexesColumn[i] = column;
tempIndexesRow[i] = row + i;
}
return new CheckResult(true,false,tempIndexesRow, tempIndexesColumn);
}
}
return new CheckResult(false, false);//íå íàøëè êîìáèíàöèþ
}
public CheckResult checkDiagonalDownUp(int row, int col)
{
CellState currentPlayer = GameManager.instance.currentPlayer;
int sum = row + col;
if (sum <= 2 || sum >=9) //ïðè òàêîé ñóììå èíäåêñîâ 4 ôèøêè â äèàãîíàëü íå ïîìåùàþòñÿ
return new CheckResult(false, false);
//ñ÷èòàåì èíäåêñ íà÷àëà äèàãîíàëè (ëåâî íèç)
int startRow = Mathf.Clamp(sum, 0, 5);
int startCol = Mathf.Clamp(sum - 5, 0, 5);
int lineLength = 0;
for (row = startRow, col = startCol; row >= 0 && col < width; row--, col++)
{
CellState cell = fieldArr[row, col];
if (cell != currentPlayer)
{
lineLength = 0;
continue;
}
lineLength++;
if (lineLength == 4)//êîìáèíàöèÿ èç 4 íàøëàñü)
{
//int[] indexesRow = new int[4];
//int[] indexesColumn = new int[4];
for (int i = 0; i < 4; i++)
{//èäåì íàçàä è çàïîëíÿåì èíäåêñû
//indexesColumn[i] = col-i;
//indexesRow[i] = row + i;
tempIndexesRow[i] = row + i;
tempIndexesColumn[i] = col-i;
}
return new CheckResult(true, false, tempIndexesRow, tempIndexesColumn);
}
}
return new CheckResult(false, false);//íå íàøëè êîìáèíàöèþ
}
public CheckResult checkDiagonalUpDown(int row, int col)
{
CellState currentPlayer = GameManager.instance.currentPlayer;
int sub = row - col;
int startRow = Mathf.Clamp(sub, 0, 2);
int startCol = Mathf.Abs(Math.Clamp(sub, -3, 0));
//CellState[] diagonalArray = getUpDownDiagonal(row, col);
int lineLength = 0;
for (row = startRow, col = startCol; row < 6 && col < 7; row++, col++)
{
CellState cell = fieldArr[row, col];
if (cell != currentPlayer)
{
lineLength = 0;
continue;
}
lineLength++;
if (lineLength == 4)//êîìáèíàöèÿ èç 4 íàøëàñü)
{
//int[] indexesRow = new int[4];
//int[] indexesColumn = new int[4];
for (int i = 0; i < 4; i++)
{//èäåì íàçàä è çàïîëíÿåì èíäåêñû
tempIndexesColumn[i] = col - i;
tempIndexesRow[i] = row - i;
//indexesColumn[i] = col - i;
//indexesRow[i] = row - i;
}
return new CheckResult(true, false, tempIndexesRow, tempIndexesColumn);
}
}
return new CheckResult(false, false);//íå íàøëè êîìáèíàöèþ
}
public int getHeight(int colIndex)
{
//ïåðåáèðàåì ðÿäû äëÿ âûáðàííîé êîëîíêè
//èùåì ñàìûé íèæíèé ñëîò â êîëîíêå, êóäà ìîæåì âñòàâèòü ôèøêó
for (int row = 5; row >= 0; row--)
{
if (fieldArr[row, colIndex] == CellState.Empty)
{
return row;
}
}
return -1;//åñëè íå íàøëè, òî áîëüøå äîáàâèòü íåëüçÿ
}
//Îïòèìèçèðîâàííûå ïðîâåðêè äëÿ áîòà
/* public bool checkRow(int row, CellState currentPlayer, CellState[,] field)
{
//Debug.Log("Ðÿä");
if (field[row, 3] != currentPlayer)
return false;
int lineLength = 0;
for (int i = 0; i < 7; i++)
{
if (field[row, i] != currentPlayer)
{
lineLength = 0;
continue;
}
lineLength++;
if (lineLength == 4)//íàøëè ðÿä èç 4 ôèøåê
return true;
}
return true;
}*/
//ïðîâåðêà íè÷üåé
public bool checkDraw()
{
for (int col = 0; col < 7; col++)
{
//åñëè åñòü õîòü îäíà íåïóñòàÿ êîëîíêà òî èãðà ïðîäîëæàåòñÿ
if (getHeight(col) != -1) return false;
}
return true;
}
/* //Ãåòòåðû äëÿ ðàçíûõ ðÿäîâ. Âîçâðàùàþò îäíîìåðíûå ìàññèâû
CellState[] getRow(int rowIndex)
{
CellState[] row = new CellState[7];
for (int col = 0; col<7; col++)
{
row[col] = fieldArr[rowIndex, col];
}
return row;
}
CellState[] getColumn(int colIndex)
{
CellState[] col = new CellState[6];
for (int row = 0; row < 6; row++)
{
col[row] = fieldArr[row, colIndex];
}
return col;
}
CellState[] getUpDownDiagonal(int row, int col)
{
int sub = row - col;
if (sub <= -4 || sub >= 3) //ïðè òàêîé ðàçíèöå èíäåêñîâ 4 ôèøêè â äèàãîíàëü íå ïîìåùàþòñÿ
return new CellState[0];
//ñ÷èòàåì èíäåêñ íà÷àëà äèàãîíàëè (ëåâî âåðõ)
int startRow = Mathf.Clamp(sub, 0, 2);
int startCol = Mathf.Abs(Math.Clamp(sub, -3, 0));
List<CellState> result = new List<CellState>();//çàðàíåå ñëîæíî îáñ÷èòàòü ñêîëüêî â äèàãîíàëè ýëåìåíòîâ, ïîýòîìó ëèñò
for (row = startRow, col = startCol; row < height && col < width; row++, col++)
{
result.Add(fieldArr[row, col]);
}
result.TrimExcess();//Óáðàòü íåçàïîëíåííûå ïîçèöèè
return result.ToArray();
}
CellState[] getDownUpDiagonal(int row, int col)
{
int sum = row + col;
if (sum <= 2 || sum >= 9) //ïðè òàêîé ñóììå èíäåêñîâ 4 ôèøêè â äèàãîíàëü íå ïîìåùàþòñÿ
return new CellState[0];
//ñ÷èòàåì èíäåêñ íà÷àëà äèàãîíàëè (ëåâî íèç)
int startRow = Mathf.Clamp(sum, 0, 5);
int startCol = Mathf.Clamp(sum - 5, 0, 5);
List<CellState> result = new List<CellState>();//çàðàíåå ñëîæíî îáñ÷èòàòü ñêîëüêî â äèàãîíàëè ýëåìåíòîâ, ïîýòîìó ëèñò
for (row = startRow, col = startCol; row >=0 && col < width; row--, col++)
{
result.Add(fieldArr[row, col]);
}
result.TrimExcess();//Óáðàòü íåçàïîëíåííûå ïîçèöèè
return result.ToArray();
}*/
}