| using System; |
| using UnityEngine; |
|
|
| namespace Unity.MLAgents.Integrations.Match3 |
| { |
| |
| |
| |
| public enum Direction |
| { |
| |
| |
| |
| Up, |
|
|
| |
| |
| |
| Down, |
|
|
| |
| |
| |
| Left, |
|
|
| |
| |
| |
| Right, |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public struct Move |
| { |
| |
| |
| |
| public int MoveIndex; |
|
|
| |
| |
| |
| public int Row; |
|
|
| |
| |
| |
| public int Column; |
|
|
| |
| |
| |
| public Direction Direction; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public static Move FromMoveIndex(int moveIndex, BoardSize maxBoardSize) |
| { |
| var maxRows = maxBoardSize.Rows; |
| var maxCols = maxBoardSize.Columns; |
|
|
| if (moveIndex < 0 || moveIndex >= NumPotentialMoves(maxBoardSize)) |
| { |
| throw new ArgumentOutOfRangeException("moveIndex"); |
| } |
| Direction dir; |
| int row, col; |
| if (moveIndex < (maxCols - 1) * maxRows) |
| { |
| dir = Direction.Right; |
| col = moveIndex % (maxCols - 1); |
| row = moveIndex / (maxCols - 1); |
| } |
| else |
| { |
| dir = Direction.Up; |
| var offset = moveIndex - (maxCols - 1) * maxRows; |
| col = offset % maxCols; |
| row = offset / maxCols; |
| } |
| return new Move |
| { |
| MoveIndex = moveIndex, |
| Direction = dir, |
| Row = row, |
| Column = col |
| }; |
| } |
|
|
| |
| |
| |
| |
| public void Next(BoardSize maxBoardSize) |
| { |
| var maxRows = maxBoardSize.Rows; |
| var maxCols = maxBoardSize.Columns; |
|
|
| var switchoverIndex = (maxCols - 1) * maxRows; |
|
|
| MoveIndex++; |
| if (MoveIndex < switchoverIndex) |
| { |
| Column++; |
| if (Column == maxCols - 1) |
| { |
| Row++; |
| Column = 0; |
| } |
| } |
| else if (MoveIndex == switchoverIndex) |
| { |
| |
| Row = 0; |
| Column = 0; |
| Direction = Direction.Up; |
| } |
| else |
| { |
| Column++; |
| if (Column == maxCols) |
| { |
| Row++; |
| Column = 0; |
| } |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public static Move FromPositionAndDirection(int row, int col, Direction dir, BoardSize maxBoardSize) |
| { |
| |
| if (row < 0 || row >= maxBoardSize.Rows) |
| { |
| throw new IndexOutOfRangeException($"row was {row}, but must be between 0 and {maxBoardSize.Rows - 1}."); |
| } |
|
|
| if (col < 0 || col >= maxBoardSize.Columns) |
| { |
| throw new IndexOutOfRangeException($"col was {col}, but must be between 0 and {maxBoardSize.Columns - 1}."); |
| } |
|
|
| |
| if ( |
| row == 0 && dir == Direction.Down || |
| row == maxBoardSize.Rows - 1 && dir == Direction.Up || |
| col == 0 && dir == Direction.Left || |
| col == maxBoardSize.Columns - 1 && dir == Direction.Right |
| ) |
| { |
| throw new IndexOutOfRangeException($"Cannot move cell at row={row} col={col} in Direction={dir}"); |
| } |
|
|
| |
| if (dir == Direction.Left) |
| { |
| dir = Direction.Right; |
| col = col - 1; |
| } |
| else if (dir == Direction.Down) |
| { |
| dir = Direction.Up; |
| row = row - 1; |
| } |
|
|
| int moveIndex; |
| if (dir == Direction.Right) |
| { |
| moveIndex = col + row * (maxBoardSize.Columns - 1); |
| } |
| else |
| { |
| var offset = (maxBoardSize.Columns - 1) * maxBoardSize.Rows; |
| moveIndex = offset + col + row * maxBoardSize.Columns; |
| } |
|
|
| return new Move |
| { |
| Row = row, |
| Column = col, |
| Direction = dir, |
| MoveIndex = moveIndex, |
| }; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| public bool InRangeForBoard(BoardSize boardSize) |
| { |
| var (otherRow, otherCol) = OtherCell(); |
| |
| var maxMoveRow = Mathf.Max(Row, otherRow); |
| var maxMoveCol = Mathf.Max(Column, otherCol); |
| return maxMoveRow < boardSize.Rows && maxMoveCol < boardSize.Columns; |
| } |
|
|
| |
| |
| |
| |
| |
| public (int Row, int Column) OtherCell() |
| { |
| switch (Direction) |
| { |
| case Direction.Up: |
| return (Row + 1, Column); |
| case Direction.Down: |
| return (Row - 1, Column); |
| case Direction.Left: |
| return (Row, Column - 1); |
| case Direction.Right: |
| return (Row, Column + 1); |
| default: |
| throw new ArgumentOutOfRangeException(); |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| public Direction OtherDirection() |
| { |
| switch (Direction) |
| { |
| case Direction.Up: |
| return Direction.Down; |
| case Direction.Down: |
| return Direction.Up; |
| case Direction.Left: |
| return Direction.Right; |
| case Direction.Right: |
| return Direction.Left; |
| default: |
| throw new ArgumentOutOfRangeException(); |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| public static int NumPotentialMoves(BoardSize maxBoardSize) |
| { |
| return maxBoardSize.Rows * (maxBoardSize.Columns - 1) + (maxBoardSize.Rows - 1) * (maxBoardSize.Columns); |
| } |
| } |
| } |
|
|