using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace _20200502
{
public partial class form : Form
{
Random random;
int[,] array;
bool start = true;
int totalScore;
int x;
int y;
int randomNum1;
int randomNum2;
Control newNumTemp;
public form()
{
InitializeComponent();
this.Init();
this.StartGame();
this.TableInit();
this.IsNumberBackgroundColor();
}
public void Init()
{
this.random = new Random();
this.newNumTemp = new Control();
}
// up 버튼 입력시 해당 방향으로 재정렬
public void UpDataSort()
{
int[,] newArr = new int[4, 4];
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (this.array[i, j] > 0)
{
for (int k = 0; k < newArr.GetLength(1); k++)
{
if (newArr[k, j] == 0)
{
if (k != 0)
{
if (newArr[k - 1, j] == this.array[i, j])
{
newArr[k - 1, j] = this.array[i, j] * 2;
this.totalScore += newArr[k - 1, j];
break;
}
}
newArr[k, j] = this.array[i, j];
break;
}
}
}
}
}
this.array = newArr;
}
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
// down 버튼 입력시 해당 방향으로 재정렬
public void DownDataSort()
{
int[,] newArr = new int[4, 4];
for (int i = 3; i >= 0; i--)
{
for (int j = 3; j >= 0; j--)
{
if (this.array[i, j] > 0)
{
for (int k = 3; k >= 0; k--)
{
if (newArr[k, j] == 0)
{
if (k != 3)
{
if (newArr[k + 1, j] == this.array[i, j])
{
newArr[k + 1, j] = this.array[i, j] * 2;
this.totalScore += newArr[k + 1, j];
break;
}
}
newArr[k, j] = this.array[i, j];
break;
}
}
}
}
}
this.array = newArr;
}
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
// left 버튼 입력시 해당 방향으로 재정렬
public void LeftDataSort()
{
int[,] newArr = new int[4, 4];
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
// 값있을 경우
if (this.array[j, i] > 0)
{
// 행
for (int k = 0; k < newArr.GetLength(1); k++)
{
if (newArr[j, k] == 0)
{
if (k != 0)
{
if (newArr[j, k - 1] == this.array[j, i])
{
newArr[j, k - 1] = this.array[j, i] * 2;
this.totalScore += newArr[j, k - 1];
break;
}
}
newArr[j, k] = this.array[j, i];
break;
}
}
}
}
}
this.array = newArr;
}
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
// right 버튼 입력시 해당 방향으로 재정렬
public void RightDataSort()
{
int[,] newArr = new int[4, 4];
for (int i = 3; i >= 0; i--)
{
for (int j = 0; j < 4; j++)
{
// 값있을 경우
if (this.array[j, i] > 0)
{
// 행
for (int k = 3; k >= 0; k--)
{
if (newArr[j, k] == 0)
{
if (k != 3)
{
if (newArr[j, k + 1] == this.array[j, i])
{
newArr[j, k + 1] = this.array[j, i] * 2;
this.totalScore += newArr[j, k + 1];
break;
}
}
newArr[j, k] = this.array[j, i];
break;
}
}
}
}
}
this.array = newArr;
}
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
// 뷰테이블에 있는 데이터, 로직 배열과 동기화
public void TableInit()
{
this.array = new int[4, 4];
foreach (Control ctrl in tableLayoutPanel1.Controls)
{
if (ctrl is Label)
{
var row = tableLayoutPanel1.GetRow(ctrl);
var col = tableLayoutPanel1.GetColumn(ctrl);
this.array[row, col] = 0;
// 값 있는 경우
if (ctrl.Text.Length > 0)
{
int myNum = int.Parse(ctrl.Text);
this.array[row, col] = myNum;
}
}
}
this.IsNumberBackgroundColor();
}
// 뷰 라벨 테이블 비우고 데이터 배열 초기화
public void NewTable()
{
foreach (Control ctrl in tableLayoutPanel1.Controls)
{
if (ctrl is Label)
{
ctrl.Text = "";
}
}
this.array = new int[4, 4];
}
// 게임 스타트시 초기값 발생
public void StartGame()
{
this.RandomXY();
this.RandomNum();
tableLayoutPanel1.GetControlFromPosition(y, x).Text = randomNum2.ToString();
this.RandomXY();
this.RandomNum();
tableLayoutPanel1.GetControlFromPosition(y, x).Text = randomNum1.ToString();
}
// 처음에 주어지는 숫자 위치 정하기
public void RandomXY()
{
// 낮은 확률로 처음 주어지는 숫자 위치 중첩 방지
while (true)
{
int tempX = random.Next(0, 4);
int tempY = random.Next(0, 4);
if (this.x != tempX && this.y != tempY)
{
this.x = tempX;
this.y = tempY;
break;
}
}
}
// 처음에 주어지는 숫자 2,4 난수 발생 로직
public void RandomNum()
{
while (true)
{
int tempNum1 = random.Next(2, 5);
int tempNum2 = random.Next(2, 5);
bool cheeck1 = false;
bool cheeck2 = false;
// 처음만 두개의 숫자 발생
if (this.start)
{
if (tempNum2 == 2 || tempNum2 == 4)
{
this.randomNum1 = tempNum2;
cheeck1 = true;
}
}
if (tempNum1 == 2 || tempNum1 == 4)
{
this.randomNum2 = tempNum1;
cheeck2 = true;
}
if (cheeck1 && cheeck2)
{
break;
}
}
}
// 턴 이후 지급되는 랜덤 숫자 생성
public void CreateNewNum()
{
while (true)
{
this.RandomXY();
if (this.array[this.x, this.y] == 0)
{
break;
}
}
this.newNumTemp.ForeColor = Color.Black;
this.RandomNum();
this.array[this.x, this.y] = this.randomNum2;
tableLayoutPanel1.GetControlFromPosition(y, x).Text = this.randomNum2.ToString();
tableLayoutPanel1.GetControlFromPosition(y, x).ForeColor = Color.IndianRed;
this.newNumTemp = tableLayoutPanel1.GetControlFromPosition(y, x);
logBox.Items.Add($"신규랜덤난수:[{x},{y}]:{this.randomNum2}");
}
// new버튼 이벤트 발생시 초기화
public void GameReset()
{
this.array = new int[4, 4];
this.start = true;
this.totalScore = 0;
this.ViewReset();
this.StartGame();
this.TableInit();
this.SetScoreView();
}
// 전체 테이블 라벨 지우고, log창 지우기
public void ViewReset()
{
foreach (Control ctrl in tableLayoutPanel1.Controls)
{
if (ctrl is Label)
{
ctrl.Text = "";
}
}
logBox.Items.Clear();
}
// sort된 배열, 뷰 테이블라벨에 재적용
public void UpdateView()
{
foreach (Control ctrl in tableLayoutPanel1.Controls)
{
if (ctrl is Label)
{
var row = tableLayoutPanel1.GetRow(ctrl);
var col = tableLayoutPanel1.GetColumn(ctrl);
ctrl.Text = "";
// 값 있는 경우
if (this.array[row, col] > 0)
{
ctrl.Text = this.array[row, col].ToString();
}
}
}
}
// 빈배열 있는지 체크
public bool EndGameCheck()
{
foreach (var item in this.array)
{
if (item == 0)
{
return true;
}
}
return false;
}
// 게임 클리어 체크
public bool ClearGameCheck()
{
foreach (var item in this.array)
{
if (item.Equals(2048))
{
return true;
}
}
return false;
}
// 연산값에 대한 뷰 컬러처리
public void IsNumberBackgroundColor()
{
int checkNum = 0;
foreach (Control ctrl in tableLayoutPanel1.Controls)
{
if (ctrl is Label)
{
ctrl.BackColor = Color.Gainsboro;
if (ctrl.Text != "")
{
checkNum = int.Parse(ctrl.Text);
if (checkNum == 8)
{
ctrl.ForeColor = Color.WhiteSmoke;
ctrl.BackColor = Color.LightSalmon;
}
else if (checkNum == 16)
{
ctrl.ForeColor = Color.WhiteSmoke;
ctrl.BackColor = Color.LightCoral;
}
else if (checkNum == 32)
{
ctrl.ForeColor = Color.WhiteSmoke;
ctrl.BackColor = Color.Coral;
}
else if (checkNum >= 64)
{
ctrl.ForeColor = Color.WhiteSmoke;
ctrl.BackColor = Color.Tomato;
}
else
{
ctrl.BackColor = Color.Silver;
ctrl.ForeColor = Color.Black;
}
}
if (ctrl.Text == "")
{
ctrl.BackColor = Color.Silver;
ctrl.ForeColor = Color.Black;
}
}
}
}
// 스코어 뷰에 누계 적용
public void SetScoreView()
{
scoreLabel.Text = this.totalScore.ToString();
}
// 개발시 배열 확인용 매소드
public void ArrayPrint()
{
for (int i = 0; i < this.array.GetLength(0); i++)
{
for (int j = 0; j < this.array.GetLength(1); j++)
{
Console.Write("[{0}, {1}]:{2} ㅣ", i, j, this.array[i, j]);
}
Console.WriteLine();
}
Console.WriteLine();
}
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ 방향킼 버튼 이벤트 리스너 ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
private void UpBtn_Click(object sender, EventArgs e)
{
if (ClearGameCheck()) { MessageBox.Show("게임 클리어!!"); }
if (EndGameCheck())
{
this.UpDataSort();
this.UpdateView();
this.CreateNewNum();
this.IsNumberBackgroundColor();
this.SetScoreView();
}
else
{
MessageBox.Show("게임 종료");
}
}
private void DownBtn_Click(object sender, EventArgs e)
{
if (ClearGameCheck()) { MessageBox.Show("게임 클리어!!"); }
if (EndGameCheck())
{
this.DownDataSort();
this.UpdateView();
this.CreateNewNum();
this.IsNumberBackgroundColor();
this.SetScoreView();
}
else
{
MessageBox.Show("게임 종료");
}
}
private void LeftBtn_Click(object sender, EventArgs e)
{
if (ClearGameCheck()) { MessageBox.Show("게임 클리어!!"); }
if (EndGameCheck())
{
this.LeftDataSort();
this.UpdateView();
this.CreateNewNum();
this.IsNumberBackgroundColor();
this.SetScoreView();
}
else
{
MessageBox.Show("게임 종료");
}
}
private void RightBtn_Click(object sender, EventArgs e)
{
if (ClearGameCheck()) { MessageBox.Show("게임 클리어!!"); }
if (EndGameCheck())
{
this.RightDataSort();
this.UpdateView();
this.CreateNewNum();
this.IsNumberBackgroundColor();
this.SetScoreView();
}
else
{
MessageBox.Show("게임 종료");
}
}
// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ new 버튼 ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
// newGame 버튼 클릭시 비우고 난수 발생하기
private void button1_Click(object sender, EventArgs e)
{
this.GameReset();
}
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ ?? ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
private void tableLayoutPanel1_Paint(object sender, PaintEventArgs e)
{
}
}
}