This repository has been archived on 2024-06-21. You can view files and clone it, but cannot push or open issues or pull requests.
CDSAE3/CDSAE3_Lian_Lian_Kan/Forms/GameControl.cs

281 lines
11 KiB
C#
Raw Normal View History

2024-03-22 09:03:01 +00:00
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;
2024-03-29 06:18:38 +00:00
using System.IO;
2024-03-22 09:03:01 +00:00
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
{
2024-03-29 06:18:38 +00:00
public partial class GameControl : UserControl, IGameControl
2024-03-22 09:03:01 +00:00
{
Board board = new Board();
2024-03-29 06:18:38 +00:00
IGameMode? iGameMode;
Queue<((int, int), Single_Block)> queue = new Queue<((int, int), Single_Block)>();//y,x
bool do_search = false;
List<Single_Block> hint_blocks = new List<Single_Block>();
2024-03-22 09:03:01 +00:00
public GameControl()
{
InitializeComponent();
2024-04-02 13:57:04 +00:00
Etcs.game_form = this;
playPanel_set(board.make_board());
iGameMode = Etcs.game_mode_form;
2024-03-22 09:03:01 +00:00
}
2024-04-02 13:57:04 +00:00
void playPanel_set(int[,]bd)
2024-03-22 09:03:01 +00:00
{
playPanel_size_change();
for (int i = 0; i < playPanel.RowCount; i++)
for (int j = 0; j < playPanel.ColumnCount; j++)
{
if (bd[i, j] == -1)
{
2024-04-02 13:57:04 +00:00
var x = new Single_Block(Etcs.trans_Image, (j, i));
2024-03-22 09:03:01 +00:00
x.Dock = DockStyle.Fill;
playPanel.Controls.Add(x, j, i);
}
else
{
2024-04-02 13:57:04 +00:00
var x = new Single_Block(bd[i, j], Etcs.def_Color, Etcs.sel_Color, (j, i));
2024-03-22 09:03:01 +00:00
x.Dock = DockStyle.Fill;
playPanel.Controls.Add(x, j, i);
}
}
}
2024-03-29 06:18:38 +00:00
/// <summary>
/// 由form和to两个点获取方向
/// </summary>
/// <param name="from">起始点</param>
/// <param name="to">终点</param>
/// <returns></returns>
2024-04-02 13:57:04 +00:00
Etcs.Direction get_Direction((int, int) from, (int, int) to) //x,y
2024-03-29 06:18:38 +00:00
{
if (from.Item1 == to.Item1)
if (from.Item2 > to.Item2)
2024-04-02 13:57:04 +00:00
return Etcs.Direction.up;
2024-03-29 06:18:38 +00:00
else
2024-04-02 13:57:04 +00:00
return Etcs.Direction.down;
2024-03-29 06:18:38 +00:00
else
if (from.Item1 > to.Item1)
2024-04-02 13:57:04 +00:00
return Etcs.Direction.left;
2024-03-29 06:18:38 +00:00
else
2024-04-02 13:57:04 +00:00
return Etcs.Direction.right;
2024-03-29 06:18:38 +00:00
}
/// <summary>
/// 设置单个点方向
/// </summary>
/// <param name="point"></param>
/// <param name="direction"></param>
/// <param name="blocks"></param>
/// <param name="decrease"></param>
/// <returns></returns>
2024-04-02 13:57:04 +00:00
async Task set_PathAsync((int, int) point, Etcs.Direction direction, List<Single_Block> blocks, int wait_time,bool is_hint)
2024-03-29 06:18:38 +00:00
{
if (wait_time != 0)
await Task.Delay(wait_time);
Control? control = playPanel.GetControlFromPosition(point.Item1, point.Item2);
if (control != null && control is Single_Block single_Block)
{
if (is_hint)
single_Block.hint_path(direction);
else
single_Block.to_path(direction);
blocks.Add(single_Block);
}
}
2024-04-02 13:57:04 +00:00
async Task to_path((int, int) from, (int, int) to, bool include_end, Etcs.Direction extra_Direction, List<Single_Block> blocks, int wait_time, bool is_hint)
2024-03-29 06:18:38 +00:00
{
var direction = get_Direction(from, to);
switch (direction)
{
2024-04-02 13:57:04 +00:00
case Etcs.Direction.up:
2024-03-29 06:18:38 +00:00
for (int i = from.Item2 - 1; i != to.Item2; i--)
2024-04-02 13:57:04 +00:00
await set_PathAsync((from.Item1, i), Etcs.Direction.up_down, blocks, wait_time,is_hint);
2024-03-29 06:18:38 +00:00
break;
2024-04-02 13:57:04 +00:00
case Etcs.Direction.down:
2024-03-29 06:18:38 +00:00
for (int i = from.Item2 + 1; i != to.Item2; i++)
2024-04-02 13:57:04 +00:00
await set_PathAsync((from.Item1, i), Etcs.Direction.up_down, blocks, wait_time,is_hint);
2024-03-29 06:18:38 +00:00
break;
2024-04-02 13:57:04 +00:00
case Etcs.Direction.right:
2024-03-29 06:18:38 +00:00
for (int i = from.Item1 + 1; i != to.Item1; i++)
2024-04-02 13:57:04 +00:00
await set_PathAsync((i, from.Item2), Etcs.Direction.left_right, blocks, wait_time,is_hint);
2024-03-29 06:18:38 +00:00
break;
2024-04-02 13:57:04 +00:00
case Etcs.Direction.left:
2024-03-29 06:18:38 +00:00
for (int i = from.Item1 - 1; i != to.Item1; i--)
2024-04-02 13:57:04 +00:00
await set_PathAsync((i, from.Item2), Etcs.Direction.left_right, blocks, wait_time,is_hint);
2024-03-29 06:18:38 +00:00
break;
}
if (include_end)
{
2024-04-02 13:57:04 +00:00
direction = ((int)direction & 3) > 0 ? (Etcs.Direction)((int)direction << 2) : (Etcs.Direction)((int)direction >> 2);
2024-03-29 06:18:38 +00:00
direction = direction | extra_Direction;
await set_PathAsync(to, direction, blocks, wait_time,is_hint);
}
}
async Task path_drawerAsync(List<(int, int)> path, int wait_time, List<Single_Block> blocks, bool is_hint)
{
switch (path.Count)
{
case 2:
2024-04-02 13:57:04 +00:00
await to_path(path[0], path[1], false, Etcs.Direction.none, blocks, wait_time,is_hint);
2024-03-29 06:18:38 +00:00
break;
case 3:
var extra_direction = get_Direction(path[1], path[2]);
await to_path(path[0], path[1], true, extra_direction, blocks, wait_time,is_hint);
2024-04-02 13:57:04 +00:00
await to_path(path[1], path[2], false, Etcs.Direction.none, blocks, wait_time,is_hint);
2024-03-29 06:18:38 +00:00
break;
case 4:
2024-04-02 13:57:04 +00:00
Etcs.Direction extra_directionA = get_Direction(path[1], path[2]), extra_directionB = get_Direction(path[2], path[3]);
2024-03-29 06:18:38 +00:00
await to_path(path[0], path[1], true, extra_directionA, blocks, wait_time,is_hint);
await to_path(path[1], path[2], true, extra_directionB, blocks, wait_time,is_hint);
2024-04-02 13:57:04 +00:00
await to_path(path[2], path[3], false, Etcs.Direction.none, blocks, wait_time,is_hint);
2024-03-29 06:18:38 +00:00
break;
}
}
internal void set_tip()
{
if (queue.Count != 1)
return;
List<List<(int, int)>> paths = board.get_tip(queue.Peek().Item1);
foreach (var path in paths)
_ = path_drawerAsync(path, 0, hint_blocks,true);
}
internal void de_set_tip()
{
foreach (var control in hint_blocks)
control.de_path();
hint_blocks.Clear();
}
2024-03-22 09:03:01 +00:00
public void Selected_Handler(Single_Block sender, SelectedEventArgs e)
{
Task.Run(() =>
{
2024-03-29 06:18:38 +00:00
iGameMode?.De_pause(this, e);
2024-03-22 09:03:01 +00:00
if (e.be_selected)
{
switch (queue.Count)
{
case 0:
queue.Enqueue((e.position, sender));
2024-03-29 06:18:38 +00:00
if (do_search)
{
de_set_tip();
set_tip();
}
2024-03-22 09:03:01 +00:00
break;
case 1:
var (posa, sendera) = queue.Dequeue();
var posb = e.position;
var (could, path) = board.test(posa, posb);
if (could)
{
2024-03-29 06:18:38 +00:00
board.decrease(posa, posb);
2024-03-22 09:03:01 +00:00
_ = Block_ClearAsync(path);
while (queue.Count() > 0)
queue.Dequeue();
}
else
{
2024-03-29 06:18:38 +00:00
if (do_search)
{
de_set_tip();
set_tip();
}
2024-03-22 09:03:01 +00:00
queue.Enqueue((e.position, sender));
sendera.deselect();
}
break;
}
}
else
{
switch (queue.Count)
{
case 0:
break;
case 1:
if (queue.Peek().Item1 == e.position)
2024-03-29 06:18:38 +00:00
{
2024-03-22 09:03:01 +00:00
queue.Dequeue();
2024-03-29 06:18:38 +00:00
if (do_search)
de_set_tip();
}
2024-03-22 09:03:01 +00:00
break;
}
}
});
}
async Task Block_ClearAsync(List<(int, int)>? path)
{
2024-03-29 06:18:38 +00:00
if (do_search == true)
foreach (Single_Block single_Block in hint_blocks)
single_Block.de_path();
List<Single_Block> blocks = new List<Single_Block>();
2024-03-22 09:03:01 +00:00
if (path == null)
return;
2024-03-29 06:18:38 +00:00
await path_drawerAsync(path, 20, blocks, false);
2024-03-22 09:03:01 +00:00
Control? controlA = playPanel.GetControlFromPosition(path[0].Item1, path[0].Item2), controlB = playPanel.GetControlFromPosition(path.Last().Item1, path.Last().Item2);
2024-04-02 13:57:04 +00:00
Etcs.info_Audio_Processer.play_random_break_soundScape();
2024-03-22 09:03:01 +00:00
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);
2024-03-29 06:18:38 +00:00
foreach (var control in blocks)
2024-03-22 09:03:01 +00:00
control.de_path();
2024-03-29 06:18:38 +00:00
iGameMode?.Score_Add(this, new AddScoreArgs { score = (blocks.Count + 2) * 10 });
2024-03-22 09:03:01 +00:00
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));
}
2024-03-29 06:18:38 +00:00
public void Exchange_Handler(object? sender, EventArgs e)
{
2024-04-02 13:57:04 +00:00
int[,] bd = board.remake_board();
2024-03-29 06:18:38 +00:00
for (int i = 0; i < bd.GetLength(0); i++)
for (int j = 0; j < bd.GetLength(1); j++)
if (bd[i, j] == -1)
continue;
else
{
Control? control = playPanel.GetControlFromPosition(j, i);
if (control != null && control is Single_Block single_Block)
single_Block.Re_create(bd[i, j], null, null, null);
}
}
public void Search_Handler(object? sender, SearchEventArgs e)
{
if (e.set_search)
{
do_search = true;
set_tip();
}
else
{
do_search = false;
de_set_tip();
}
}
2024-03-22 09:03:01 +00:00
}
}