213 lines
6.2 KiB
C#
213 lines
6.2 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
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);
|
|
}
|
|
|
|
//Îñíîâíûå ïðîâåðêè ñ ðàçâåðíóòûì ðåçóëüòàòîì
|
|
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 < width; 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 = height - 1; row >= 0; row--)
|
|
{
|
|
CellState cell = fieldArr[row, column];
|
|
if (cell != currentPlayer)
|
|
{
|
|
lineLength = 0;
|
|
continue;
|
|
}
|
|
lineLength++;
|
|
|
|
if (lineLength == 4)//íàøëè ðÿä èç 4 ôèøåê
|
|
{
|
|
for (int i = 0; i < 4; 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;
|
|
|
|
// Äèàãîíàëü ñëèøêîì êîðîòêàÿ, åñëè ñóììà ìåíüøå ìèíèìàëüíîé (3) èëè áîëüøå ìàêñèìàëüíîé (height+width-4)
|
|
if (sum < 3 || sum > height + width - 4)
|
|
return new CheckResult(false, false);
|
|
|
|
// Âû÷èñëÿåì íà÷àëüíóþ òî÷êó äèàãîíàëè
|
|
int startRow = Mathf.Clamp(sum, 0, height - 1);
|
|
int startCol = Mathf.Clamp(sum - (height - 1), 0, width - 1);
|
|
|
|
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)
|
|
{
|
|
for (int i = 0; i < 4; 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;
|
|
|
|
// Íà÷àëüíàÿ òî÷êà äèàãîíàëè, ïðîõîäÿùåé ÷åðåç (row, col)
|
|
int startRow = sub >= 0 ? sub : 0;
|
|
int startCol = sub >= 0 ? 0 : -sub;
|
|
|
|
int lineLength = 0;
|
|
|
|
for (row = startRow, col = startCol; row < height && col < width; row++, col++)
|
|
{
|
|
CellState cell = fieldArr[row, col];
|
|
if (cell != currentPlayer)
|
|
{
|
|
lineLength = 0;
|
|
continue;
|
|
}
|
|
lineLength++;
|
|
if (lineLength == 4)
|
|
{
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
tempIndexesColumn[i] = col - i;
|
|
tempIndexesRow[i] = row - i;
|
|
}
|
|
return new CheckResult(true, false, tempIndexesRow, tempIndexesColumn);
|
|
}
|
|
}
|
|
return new CheckResult(false, false);
|
|
}
|
|
|
|
public int getHeight(int colIndex)
|
|
{
|
|
//ïåðåáèðàåì ðÿäû äëÿ âûáðàííîé êîëîíêè
|
|
//èùåì ñàìûé íèæíèé ñëîò â êîëîíêå, êóäà ìîæåì âñòàâèòü ôèøêó
|
|
for (int row = height-1; row >= 0; row--)
|
|
{
|
|
if (fieldArr[row, colIndex] == CellState.Empty)
|
|
{
|
|
return row;
|
|
}
|
|
}
|
|
return -1;//åñëè íå íàøëè, òî áîëüøå äîáàâèòü íåëüçÿ
|
|
}
|
|
|
|
//ïðîâåðêà íè÷üåé
|
|
public bool checkDraw()
|
|
{
|
|
for (int col = 0; col < width; col++)
|
|
{
|
|
//åñëè åñòü õîòü îäíà íåïóñòàÿ êîëîíêà òî èãðà ïðîäîëæàåòñÿ
|
|
if (getHeight(col) != -1) return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|