游戏板算法

时间:2010-09-17 23:57:25

标签: c#

我得到了一系列具有三个属性的游戏作品的字典:

地址=游戏中的位置
偏移=从游戏块连接的左侧偏移
宽度=游戏棋子的宽度(一,二或三宽)

游戏板本身是6宽5高(总共30个可能的位置)

25 26 27 28 29 30
19 20 21 22 23 24
13 14 15 16 17 18
07 08 09 10 11 12
01 02 03 04 05 06

每个号码都是电路板上的相应地址。

我希望能够将所有这些片段添加到ObservableCollection<GameRow> GameRows其中

这样的集合中
public class GameRow
{
    public ObservableCollection<GamePiece> Row { get; set; }

    public GameRow(ArrayList<GamePiece> gamePieces)
    {
        Row = new ObservableCollection<GamePiece>();

        foreach (GamePiece gamePiece in gamePieces)
        {
            Row.Add(gamePiece);
        }
    }
}

public class GamePiece
{
    public string Width { get; set; }  
    public string Color { get; set; }
    public int Address {get; set}
}

我还需要为棋盘上任何未使用的区域创建一个游戏,单个宽度和灰色(其他游戏棋子应该是黄色)。

以下是游戏内容:

一个广泛的:
X(偏移= 0)

两宽:
0X(偏移= 1)

三宽
0X0(偏移= 1)

X =报告的内容是该作品的地址
0 =它占据的空白区域。

我正试图想出一种方法来解析我收到GameRows的游戏片段。

示例:

让我说我得到三件。 {地址= 2,宽度= 1,偏移= 0},{地址= 12,宽度= 2,偏移= 1},{地址= 23,宽度= 3,偏移= 1}

我知道地址2件将位于第一排并占据位置02,该板的其余游戏部件应为空白游戏,宽度为1.地址12的部分将位于第二行行和地点11和12.地址23的作品将在第4行并占据第22,23,24位.ObservableCollection GameRows将包含五个GameRow对象。第4行的GameRow对象将包含Row集合中的4个对象。前三个是空白部分将是{宽度= 1,颜色=灰色},最后一个将是{宽度= 3,颜色=黄色}

2 个答案:

答案 0 :(得分:2)

基本上用空的或灰色的碎片创建一块板。处理字典,删除不再需要的灰色片段并添加黄色片段。然后逐行处理板以返回行数组。包含测试用例的单元测试。修改ROWS和COLS以适应任何规模的电路板。

    public class UnitTest1
{
    int ROWS = 5;
    int COLS = 6;

    public class GamePiece
    {
        public int Width;
        public string Color;
        public int Address;
        public int Offset;

    }
    public class GameRow
    {
        public List<GamePiece> Row = new List<GamePiece>();

    }

    private void initializeBoard(GamePiece[] board) {
        for(int i = 1; i < board.Length; i++) board[i] = EmptyPiece(i);
    }

    private GamePiece EmptyPiece(int address)
    {
        return new GamePiece
        {
            Address = address,
            Width = 1,
            Color = "Gray",
            Offset = 0
        };
    }

    private int ComputeRow(int address)
    {
        return ((address - 1) / COLS);
    }

    private void processDictionary(GamePiece[] board, Dictionary<int,GamePiece> d)
    {
        foreach (var piece in d.Values)
        {
            for (int i = 0; i < piece.Width; i++)
            {
                board[piece.Address - piece.Offset + i] = null;
            }
            board[piece.Address] = piece;
        }
    }

    private GameRow[] convertBoardtoRows(GamePiece[] board)
    {
        var rows = new GameRow[ROWS];
        for (int i = 0; i < rows.Length; i++) rows[i] = new GameRow();
        for (int i = 1; i < board.Length; i++)
        {
            if (board[i] != null)
            {
                rows[ComputeRow(i)].Row.Add(board[i]);
            }
        }
        return rows;
    }

    public GameRow[] ProcessPieces(Dictionary<int, GamePiece> dictionary)
    {
        GamePiece[] board = new GamePiece[ROWS*COLS+1];
        initializeBoard(board);
        processDictionary(board, dictionary);
        return convertBoardtoRows(board);
    }
    [TestMethod]
    public void TestMethod1()
    {
        var dictionary = new Dictionary<int, GamePiece>();
        dictionary.Add(1, new GamePiece { Address = 2, Width = 1, Offset = 0, Color = "Yellow" });
        dictionary.Add(2, new GamePiece { Address = 12, Width = 2, Offset = 1, Color = "Yellow" });
        dictionary.Add(3, new GamePiece { Address = 23, Width = 3, Offset = 1, Color = "Yellow" });

        var rows = ProcessPieces(dictionary);

        Assert.IsTrue(rows[0].Row.Count == 6);
        Assert.IsTrue(rows[0].Row.Where(p => p.Color == "Yellow").Count() == 1);
        Assert.IsTrue(rows[0].Row.Where(p => p.Color == "Gray").Count() == 5);
        var piece = rows[0].Row.Where(p => p.Color == "Yellow").First();
        Assert.IsTrue(piece.Address == 2);

        Assert.IsTrue(rows[1].Row.Count == 5);
        Assert.IsTrue(rows[1].Row.Where(p => p.Color == "Yellow").Count() == 1);
        Assert.IsTrue(rows[1].Row.Where(p => p.Color == "Gray").Count() == 4);
        Assert.IsTrue(rows[1].Row.Where(p => p.Address == 11).Count() == 0);
        piece = rows[1].Row.Where(p => p.Color == "Yellow").First();
        Assert.IsTrue(piece.Address == 12);

        Assert.IsTrue(rows[2].Row.Count == 6);
        Assert.IsTrue(rows[2].Row.Where(p => p.Color == "Yellow").Count() == 0);
        Assert.IsTrue(rows[2].Row.Where(p => p.Color == "Gray").Count() == 6);

        Assert.IsTrue(rows[3].Row.Count == 4);
        Assert.IsTrue(rows[3].Row.Where(p => p.Color == "Yellow").Count() == 1);
        Assert.IsTrue(rows[3].Row.Where(p => p.Color == "Gray").Count() == 3);

        Assert.IsTrue(rows[4].Row.Count == 6);
        Assert.IsTrue(rows[4].Row.Where(p => p.Color == "Yellow").Count() == 0);
        Assert.IsTrue(rows[4].Row.Where(p => p.Color == "Gray").Count() == 6);
    }
}

答案 1 :(得分:0)

为了简洁起见,我将Offset包括在GamePiece课程中。

public class GamePiece
{
    public string Width { get; set; }  
    public string Color { get; set; }
    public int Address {get; set}
    public int Offset {get; set }
}

我也忽略了下面引用的函数CreateOccupiedPiece的详细信息:

var d = new Dictionary<int, string>();

int rowWidth;
int curCol;
int address;
string value;
GamePiece curPiece;

for (int rowNum=1; rowNum<=6; rowNum++)
{
   rowWidth = 0;
   curCol = 1;
   while (rowWidth < 6) && (curCol <=6)
   {
      address = 6*(RowNum-1) + (curCol)

      if (d.TryGetValue(address, out value))
      {
         // CreateOccupiedPiece returns New Populated GamePiece
         curPiece = CreateOccupiedPiece(value);

         // Offset value will be tell us how many previous GamePieces to delete
         // as well as how much to adjust our rowWidth             
         if (curPiece.Offset > 0)
         {
            list.RemoveRange((curCol - curPiece.Offset - 1), curPiece.Offset);
            rowWidth = rowWidth - curPiece.Offset;
         }            
      }
      else
      {
         // Just add an empty space (gray, 1-width piece, at location)
         curPiece = new GamePiece("Gray", "1", address); 
      } 
      Row.Add(curPiece);
      curCol++;
      rowWidth = rowWidth + Convert.ToInt32(curPiece.Width);
   }
}