Skip to content

Match3 example - special pieces #4575

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Oct 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ MonoBehaviour:
Rows: 9
Columns: 8
NumCellTypes: 6
NumSpecialTypes: 2
RandomSeed: -1
--- !u!114 &3508723250470608013
MonoBehaviour:
Expand All @@ -135,7 +136,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 530d2f105aa145bd8a00e021bdd925fd, type: 3}
m_Name:
m_EditorClassIdentifier:
UseVectorObservations: 1
ObservationType: 0
--- !u!1 &3508723250774301855
GameObject:
m_ObjectHideFlags: 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ MonoBehaviour:
Rows: 9
Columns: 8
NumCellTypes: 6
NumSpecialTypes: 2
RandomSeed: -1
--- !u!114 &2118285884327540683
MonoBehaviour:
Expand All @@ -166,4 +167,4 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 530d2f105aa145bd8a00e021bdd925fd, type: 3}
m_Name:
m_EditorClassIdentifier:
UseVectorObservations: 1
ObservationType: 0
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ MonoBehaviour:
Rows: 9
Columns: 8
NumCellTypes: 6
NumSpecialTypes: 2
RandomSeed: -1
--- !u!114 &3019509692332007780
MonoBehaviour:
Expand Down
40 changes: 40 additions & 0 deletions Project/Assets/ML-Agents/Examples/Match3/Scenes/Match3.unity
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,11 @@ PrefabInstance:
propertyPath: m_Name
value: Match3VisualObs (3)
objectReference: {fileID: 0}
- target: {fileID: 3019509691567202678, guid: aaa471bd5e2014848a66917476671aed,
type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: aaa471bd5e2014848a66917476671aed, type: 3}
--- !u!1 &327661542
Expand Down Expand Up @@ -611,6 +616,16 @@ PrefabInstance:
propertyPath: m_Name
value: Match3VisualObs (1)
objectReference: {fileID: 0}
- target: {fileID: 3019509691567202678, guid: aaa471bd5e2014848a66917476671aed,
type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3019509692332007790, guid: aaa471bd5e2014848a66917476671aed,
type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: aaa471bd5e2014848a66917476671aed, type: 3}
--- !u!1001 &1278119417
Expand Down Expand Up @@ -685,6 +700,11 @@ PrefabInstance:
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
- target: {fileID: 2118285884327540673, guid: 6944ca02359f5427aa13c8551236a824,
type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 6944ca02359f5427aa13c8551236a824, type: 3}
--- !u!1001 &1479255359
Expand Down Expand Up @@ -966,6 +986,11 @@ PrefabInstance:
propertyPath: m_Name
value: Match3VisualObs (2)
objectReference: {fileID: 0}
- target: {fileID: 3019509691567202678, guid: aaa471bd5e2014848a66917476671aed,
type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: aaa471bd5e2014848a66917476671aed, type: 3}
--- !u!1001 &2118285882709515366
Expand Down Expand Up @@ -1035,6 +1060,16 @@ PrefabInstance:
propertyPath: m_Name
value: Match3VectorObs
objectReference: {fileID: 0}
- target: {fileID: 2118285883905619929, guid: 6944ca02359f5427aa13c8551236a824,
type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
- target: {fileID: 2118285884327540673, guid: 6944ca02359f5427aa13c8551236a824,
type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
- target: {fileID: 2118285884327540680, guid: 6944ca02359f5427aa13c8551236a824,
type: 3}
propertyPath: UseVectorObservations
Expand Down Expand Up @@ -1109,5 +1144,10 @@ PrefabInstance:
propertyPath: m_Name
value: Match3VisualObs
objectReference: {fileID: 0}
- target: {fileID: 3019509691567202678, guid: aaa471bd5e2014848a66917476671aed,
type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: aaa471bd5e2014848a66917476671aed, type: 3}
53 changes: 41 additions & 12 deletions Project/Assets/ML-Agents/Examples/Match3/Scripts/Match3Board.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ public class Match3Board : AbstractBoard

public const int k_EmptyCell = -1;

int[,] m_Cells;
(int, int)[,] m_Cells;
bool[,] m_Matched;

System.Random m_Random;

void Awake()
{
m_Cells = new int[Columns, Rows];
m_Cells = new (int, int)[Columns, Rows];
m_Matched = new bool[Columns, Rows];

m_Random = new System.Random(RandomSeed == -1 ? gameObject.GetInstanceID() : RandomSeed);
Expand All @@ -42,7 +42,12 @@ public override bool MakeMove(Move move)

public override int GetCellType(int row, int col)
{
return m_Cells[col, row];
return m_Cells[col, row].Item1;
}

public override int GetSpecialType(int row, int col)
{
return m_Cells[col, row].Item2;
}

public override bool IsMoveValid(Move m)
Expand All @@ -67,7 +72,7 @@ public bool MarkMatchedCells(int[,] cells = null)
var matchedRows = 0;
for (var iOffset = i; iOffset < Rows; iOffset++)
{
if (m_Cells[j, i] != m_Cells[j, iOffset])
if (m_Cells[j, i].Item1 != m_Cells[j, iOffset].Item1)
{
break;
}
Expand All @@ -89,7 +94,7 @@ public bool MarkMatchedCells(int[,] cells = null)
var matchedCols = 0;
for (var jOffset = j; jOffset < Columns; jOffset++)
{
if (m_Cells[j, i] != m_Cells[jOffset, i])
if (m_Cells[j, i].Item1 != m_Cells[jOffset, i].Item1)
{
break;
}
Expand Down Expand Up @@ -122,7 +127,7 @@ public int ClearMatchedCells()
if (m_Matched[j, i])
{
numMatchedCells++;
m_Cells[j, i] = k_EmptyCell;
m_Cells[j, i] = (k_EmptyCell, 0);
}
}
}
Expand All @@ -141,7 +146,7 @@ public bool DropCells()
for (var readIndex = 0; readIndex < Rows; readIndex++)
{
m_Cells[j, writeIndex] = m_Cells[j, readIndex];
if (m_Cells[j, readIndex] != k_EmptyCell)
if (m_Cells[j, readIndex].Item1 != k_EmptyCell)
{
writeIndex++;
}
Expand All @@ -152,7 +157,7 @@ public bool DropCells()
for (; writeIndex < Rows; writeIndex++)
{
madeChanges = true;
m_Cells[j, writeIndex] = k_EmptyCell;
m_Cells[j, writeIndex] = (k_EmptyCell, 0);
}
}

Expand All @@ -166,18 +171,18 @@ public bool FillFromAbove()
{
for (var j = 0; j < Columns; j++)
{
if (m_Cells[j, i] == k_EmptyCell)
if (m_Cells[j, i].Item1 == k_EmptyCell)
{
madeChanges = true;
m_Cells[j, i] = m_Random.Next(0, NumCellTypes);
m_Cells[j, i] = (GetRandomCellType(), GetRandomSpecialType());
}
}
}

return madeChanges;
}

public int[,] Cells
public (int, int)[,] Cells
{
get { return m_Cells; }
}
Expand All @@ -194,7 +199,7 @@ public void InitRandom()
{
for (var j = 0; j < Columns; j++)
{
m_Cells[j, i] = m_Random.Next(0, NumCellTypes);
m_Cells[j, i] = (GetRandomCellType(), GetRandomSpecialType());
}
}
}
Expand Down Expand Up @@ -226,6 +231,30 @@ void ClearMarked()
}
}

int GetRandomCellType()
{
return m_Random.Next(0, NumCellTypes);
}

int GetRandomSpecialType()
{
// 1/N chance to get a type-2 special
// 2/N chance to get a type-1 special
// otherwise 0 (boring)
var N = 10;
var val = m_Random.Next(0, N);
if (val == 0)
{
return 2;
}

if (val <= 2)
{
return 1;
}

return 0;
}

}
}
22 changes: 20 additions & 2 deletions Project/Assets/ML-Agents/Examples/Match3/Scripts/Match3Drawer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void OnDrawGizmos()
{
for (var j = 0; j < board.Columns; j++)
{
var value = board.Cells != null ? board.Cells[j, i] : Match3Board.k_EmptyCell;
var value = board.Cells != null ? board.GetCellType(i, j) : Match3Board.k_EmptyCell;
if (value >= 0 && value < s_Colors.Length)
{
Gizmos.color = s_Colors[value];
Expand All @@ -51,7 +51,25 @@ void OnDrawGizmos()
var pos = new Vector3(j, i, 0);
pos *= cubeSpacing;

Gizmos.DrawCube(transform.TransformPoint(pos), cubeSize * Vector3.one);
var specialType = board.Cells != null ? board.GetSpecialType(i, j) : 0;
if (specialType == 2)
{
Gizmos.DrawCube(transform.TransformPoint(pos), cubeSize * new Vector3(1f, .5f, .5f));
Gizmos.DrawCube(transform.TransformPoint(pos), cubeSize * new Vector3(.5f, 1f, .5f));
Gizmos.DrawCube(transform.TransformPoint(pos), cubeSize * new Vector3(.5f, .5f, 1f));
}
else if (specialType == 1)
{
Gizmos.DrawSphere(transform.TransformPoint(pos), .5f * cubeSize);
}
else
{
Gizmos.DrawCube(transform.TransformPoint(pos), cubeSize * Vector3.one);
}





Gizmos.color = Color.yellow;
if (board.Matched != null && board.Matched[j, i])
Expand Down
Binary file not shown.
Binary file not shown.
6 changes: 6 additions & 0 deletions com.unity.ml-agents.extensions/Documentation~/Match3.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ We provide some utilities to integrate ML-Agents with Match-3 games.
## AbstractBoard class
The `AbstractBoard` is the bridge between ML-Agents and your game. It allows ML-Agents to
* ask your game what the "color" of a cell is
* ask whether the cell is a "special" piece type or not
* ask your game whether a move is allowed
* request that your game make a move

Expand All @@ -17,6 +18,11 @@ Returns the "color" of piece at the given row and column.
This should be between 0 and NumCellTypes-1 (inclusive).
The actual order of the values doesn't matter.

#### `public abstract int GetSpecialType(int row, int col)`
Returns the special type of the piece at the given row and column.
This should be between 0 and NumSpecialTypes (inclusive).
The actual order of the values doesn't matter.

#### `public abstract bool IsMoveValid(Move m)`
Check whether the particular `Move` is valid for the game.
The actual results will depend on the rules of the game, but we provide the `SimpleIsMoveValid()` method
Expand Down
30 changes: 27 additions & 3 deletions com.unity.ml-agents.extensions/Runtime/Match3/AbstractBoard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,29 @@ namespace Unity.MLAgents.Extensions.Match3
{
public abstract class AbstractBoard : MonoBehaviour
{
/// <summary>
/// Number of rows on the board
/// </summary>
public int Rows;

/// <summary>
/// Number of columns on the board
/// </summary>
public int Columns;

/// <summary>
/// Maximum number of different types of cells (colors, pieces, etc).
/// </summary>
public int NumCellTypes;

/// <summary>
/// Maximum number of special types. This can be zero, in which case
/// all cells of the same type are assumed to be equivalent.
/// </summary>
public int NumSpecialTypes;

/// <summary>
/// Returns the "color" of piece at the given row and column.
/// Returns the "color" of the piece at the given row and column.
/// This should be between 0 and NumCellTypes-1 (inclusive).
/// The actual order of the values doesn't matter.
/// </summary>
Expand All @@ -20,6 +36,16 @@ public abstract class AbstractBoard : MonoBehaviour
/// <returns></returns>
public abstract int GetCellType(int row, int col);

/// <summary>
/// Returns the special type of the piece at the given row and column.
/// This should be between 0 and NumSpecialTypes (inclusive).
/// The actual order of the values doesn't matter.
/// </summary>
/// <param name="row"></param>
/// <param name="col"></param>
/// <returns></returns>
public abstract int GetSpecialType(int row, int col);

/// <summary>
/// Check whether the particular Move is valid for the game.
/// The actual results will depend on the rules of the game, but we provide SimpleIsMoveValid()
Expand All @@ -38,8 +64,6 @@ public abstract class AbstractBoard : MonoBehaviour
/// <returns></returns>
public abstract bool MakeMove(Move m);

// TODO handle "special" cell types?

public IEnumerable<Move> AllMoves()
{
var currentMove = Move.FromMoveIndex(0, Rows, Columns);
Expand Down
Loading