207 lines
8.6 KiB
C#
207 lines
8.6 KiB
C#
using CDSAE3_Lian_Lian_Kan.Board_funcs;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.ComponentModel.Design;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;
|
|
|
|
namespace CDSAE3_Lian_Lian_Kan.Forms
|
|
{
|
|
public partial class GameControl : UserControl, IBeSelected
|
|
{
|
|
Board board = new Board();
|
|
IGameMode iGameMode;
|
|
public GameControl()
|
|
{
|
|
InitializeComponent();
|
|
board.make_board();
|
|
Settings.game_form = this;
|
|
playPanel_set();
|
|
iGameMode = Settings.game_mode_form;
|
|
}
|
|
void playPanel_set()
|
|
{
|
|
int[,] bd;
|
|
if (board.Bd == null)
|
|
{
|
|
board.make_board();
|
|
bd = board.Bd ?? new int[0, 0];
|
|
if (bd.Length == 0)
|
|
throw new Exception("bd is null");
|
|
}
|
|
else
|
|
bd = board.Bd;
|
|
playPanel_size_change();
|
|
for (int i = 0; i < playPanel.RowCount; i++)
|
|
for (int j = 0; j < playPanel.ColumnCount; j++)
|
|
{
|
|
if (bd[i, j] == -1)
|
|
{
|
|
var x = new Single_Block(Settings.trans_Image, (j, i));
|
|
x.Dock = DockStyle.Fill;
|
|
playPanel.Controls.Add(x, j, i);
|
|
}
|
|
else
|
|
{
|
|
var x = new Single_Block(bd[i, j], Settings.def_Color, Settings.sel_Color, (j, i));
|
|
x.Dock = DockStyle.Fill;
|
|
playPanel.Controls.Add(x, j, i);
|
|
}
|
|
}
|
|
}
|
|
Queue<((int, int), Single_Block)> queue = new Queue<((int, int), Single_Block)>();//y,x
|
|
public void Selected_Handler(Single_Block sender, SelectedEventArgs e)
|
|
{
|
|
Task.Run(() =>
|
|
{
|
|
iGameMode.De_pause(this, e);
|
|
if (e.be_selected)
|
|
{
|
|
switch (queue.Count)
|
|
{
|
|
case 0:
|
|
queue.Enqueue((e.position, sender));
|
|
break;
|
|
case 1:
|
|
var (posa, sendera) = queue.Dequeue();
|
|
var posb = e.position;
|
|
var (could, path) = board.test(posa, posb);
|
|
if (could)
|
|
{
|
|
_ = Block_ClearAsync(path);
|
|
while (queue.Count() > 0)
|
|
queue.Dequeue();
|
|
if (board.Bd is null) throw new Exception("No usable board. How come?");
|
|
board.Bd[posa.Item2, posa.Item1] = -1;
|
|
board.Bd[posb.Item2, posb.Item1] = -1;
|
|
}
|
|
else
|
|
{
|
|
queue.Enqueue((e.position, sender));
|
|
sendera.deselect();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (queue.Count)
|
|
{
|
|
case 0:
|
|
break;
|
|
case 1:
|
|
if (queue.Peek().Item1 == e.position)
|
|
queue.Dequeue();
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
async Task Block_ClearAsync(List<(int, int)>? path)
|
|
{
|
|
List<Single_Block> paths = new List<Single_Block>();
|
|
if (path == null)
|
|
return;
|
|
Func<(int, int), (int, int), Settings.Direction> get_Direction = ((int, int) from, (int, int) to) =>//x,y
|
|
{
|
|
if (from.Item1 == to.Item1)
|
|
if (from.Item2 > to.Item2)
|
|
return Settings.Direction.up;
|
|
else
|
|
return Settings.Direction.down;
|
|
else
|
|
if (from.Item1 > to.Item1)
|
|
return Settings.Direction.left;
|
|
else
|
|
return Settings.Direction.right;
|
|
};
|
|
Func<(int, int), Settings.Direction, Task> set_Path = async ((int, int) point, Settings.Direction direction) =>
|
|
{
|
|
await Task.Delay(20);
|
|
Control? control = playPanel.GetControlFromPosition(point.Item1, point.Item2);
|
|
if (control != null && control is Single_Block single_Block)
|
|
{
|
|
single_Block.to_path(direction);
|
|
paths.Add(single_Block);
|
|
}
|
|
};
|
|
Func<(int, int), (int, int), bool, Settings.Direction, Task> to_path = async ((int, int) from, (int, int) to, bool include_end, Settings.Direction extra_Direction) =>
|
|
{
|
|
var direction = get_Direction(from, to);
|
|
switch (direction)
|
|
{
|
|
case Settings.Direction.up:
|
|
for (int i = from.Item2 - 1; i != to.Item2; i--)
|
|
await set_Path((from.Item1, i), Settings.Direction.up_down);
|
|
break;
|
|
case Settings.Direction.down:
|
|
for (int i = from.Item2 + 1; i != to.Item2; i++)
|
|
await set_Path((from.Item1, i), Settings.Direction.up_down);
|
|
break;
|
|
case Settings.Direction.right:
|
|
for (int i = from.Item1 + 1; i != to.Item1; i++)
|
|
await set_Path((i, from.Item2), Settings.Direction.left_right);
|
|
break;
|
|
case Settings.Direction.left:
|
|
for (int i = from.Item1 - 1; i != to.Item1; i--)
|
|
await set_Path((i, from.Item2), Settings.Direction.left_right);
|
|
break;
|
|
}
|
|
if (include_end)
|
|
{
|
|
direction = direction | extra_Direction;
|
|
await set_Path(to, direction);
|
|
}
|
|
};
|
|
switch (path.Count)
|
|
{
|
|
case 2:
|
|
await to_path(path[0], path[1], false, 0);
|
|
break;
|
|
case 3:
|
|
var extra_direction = get_Direction(path[1], path[2]);
|
|
await to_path(path[0], path[1], true, extra_direction);
|
|
await to_path(path[1], path[2], false, Settings.Direction.none);
|
|
break;
|
|
case 4:
|
|
Settings.Direction extra_directionA = get_Direction(path[1], path[2]), extra_directionB = get_Direction(path[2], path[3]);
|
|
await to_path(path[0], path[1], true, extra_directionA);
|
|
await to_path(path[1], path[2], true, extra_directionB);
|
|
await to_path(path[2], path[3], false, Settings.Direction.none);
|
|
break;
|
|
}
|
|
Control? controlA = playPanel.GetControlFromPosition(path[0].Item1, path[0].Item2), controlB = playPanel.GetControlFromPosition(path.Last().Item1, path.Last().Item2);
|
|
if (controlA != null && controlB != null && controlA is Single_Block single_BlockA && controlB is Single_Block single_BlockB)
|
|
{
|
|
single_BlockA.destroyAsync();
|
|
single_BlockB.destroyAsync();
|
|
}
|
|
await Task.Delay(200);
|
|
foreach (var control in paths)
|
|
control.de_path();
|
|
iGameMode.Score_Add(this, new AddScoreArgs { score = (paths.Count + 2)*10 });
|
|
board.Total -= 2;
|
|
}
|
|
|
|
void playPanel_size_change()
|
|
{
|
|
var (width, height) = board.size;
|
|
playPanel.RowCount = height + 2;
|
|
playPanel.ColumnCount = width + 2;
|
|
playPanel.ColumnStyles[0] = new ColumnStyle(SizeType.Percent, 100F);
|
|
playPanel.RowStyles[0] = new RowStyle(SizeType.Percent, 100F);
|
|
for (int i = 0; i < width + 1; i++)
|
|
playPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
|
|
for (int i = 0; i < height + 1; i++)
|
|
playPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
|
|
}
|
|
}
|
|
}
|