Tak jsem to pexeso testoval, ještě byla chyba ve vyhodnocení výhry. Taky jsem tam přidal nastavení obtížnosti.
Tady je odkaz na (doufám) finální verzi:
http://www85.zippyshare.com/v/4gt6HiEE/file.html
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
namespace SWPexeso
{
public partial class Form1 : Form
{
private const int players_count_max = 4; //pro jednoduchost jsem nastavil 4 hráče jako maximum
private const int card_distance = 52; //muj rozestup karet
bool click_on_stop, playing;
int last_index, current_player, players_count, click_count, min, sec, completed;
int IQ = 7; // počet kroků, které is AI zapamatuje <--
int[] player = new int[players_count_max];
bool[] player_ai = new bool[players_count_max];
Random random = new Random();
Card[] cards = new Card[20];
List<int> memory = new List<int>();
public Form1()
{
InitializeComponent();
}
public void StopGame()
{
click_on_stop = true;
Application.DoEvents();
GameTimer.Stop();
}
//překreslení celého plátna
private void Canvas_Paint(object sender, PaintEventArgs e)
{
for (int x = 0; x < 5; x++)
{
for (int y = 0; y < 4; y++)
{
int index = (y * 5) + x;
int imageindex = (cards[index].covered) ? 0 : cards[index].picture;
e.Graphics.DrawImage(cardImages.Images[imageindex], (x * card_distance) + 2, (y * card_distance) + 2);
}
}
}
//výběr myší
private void Canvas_MouseDown(object sender, MouseEventArgs e)
{
if (player_ai[current_player] || !playing) return; //když hraje pc, nebo se nehraje, tak nic..
else //pokud nehraje aktuálně počítač:
{ //výpočet karty na kterou bylo klepnuto
int x = e.Location.X / card_distance;
int y = e.Location.Y / card_distance;
if (x < 5 && y < 4)
{
int index = (y * 5) + x;
ClickOn(index);
}
}
}
//překreslení pouze definované karty
private void Repaint(int index)
{
int y = index / 5;
int x = index - (y * 5);
try
{
int imageindex = (cards[index].covered) ? 0 : cards[index].picture;
Graphics g = Canvas.CreateGraphics();
g.DrawImage(cardImages.Images[imageindex], (x * card_distance) + 2, (y * card_distance) + 2);
}
catch { }
}
/// <summary>
/// událost po kliknutí na kartu
/// </summary>
/// <param name="index">index karty na kterou bylo kliknuto</param>
private void ClickOn(int index)
{
if (index != last_index && cards[index].enabled && cards[index].covered)
{
cards[index].covered = false; //otočit kartu
click_count++; //připočítat otočenou..
Repaint(index); //překreslit kartu
Thread.Sleep(600); //pozastavit, aby se balo postřehnout, která karta byla otočena
if (click_count > 1) //pokud jsou obě karty otočeny
{
if (cards[last_index].picture == cards[index].picture) //pokud se shodují
{
player[current_player]++; //připočítat body aktivnímu hráči
cards[index].enabled = false; //uzamčít kartu 1
cards[last_index].enabled = false; //uzamčít kartu 2
completed++;
}
else //karty nejsou shodné
{
cards[index].covered = true; //otočit zpět kartu 1
cards[last_index].covered = true; //otočit zpět kartu 2
if (IQ > 0) //<--
{
memory.Add(index); // AI si zapamatuje poslední karty
memory.Add(last_index); // AI si zapamatuje poslední karty
if ((memory.Count / 2) > IQ)
{
memory.RemoveAt(0);
memory.RemoveAt(1);
}
}
Repaint(index); //překreslit kartu
Repaint(last_index); //překreslit kartu
NextPlayer(); //přepnout hráče
}
click_count = 0; //vymazat počet otočených karet
last_index = -1; //vymazat paměť, která karta byla otočena jako první
}
else //je otočena pouze jedna karta
{
last_index = index; //zapamatovat si, která karta je otočena jako první
}
switch (current_player) //zobrazit aktuální bodový stav
{
case 0: laPlayer1.Text = player[0].ToString(); break;
case 1: laPlayer2.Text = player[1].ToString(); break;
case 2: laPlayer3.Text = player[2].ToString(); break;
case 3: laPlayer4.Text = player[3].ToString(); break;
}
if (completed == 10) //pokud byly všechny karty otočeny
{
GameTimer.Stop(); //zastavit měření času
try
{
System.Media.SoundPlayer snd = new System.Media.SoundPlayer(@"C:\Windows\Media\tada.wav");
snd.Play(); //můžeme přehrát nějaký zvuk
}
catch { }
playing = false;
//výpis výsledků:
int winner = 0;
for (int i = 0; i < players_count; i++)
{
if (player[i] > player[winner]) winner = i;
}
int winners = 0;
for (int i = 0; i < players_count; i++)
{
if (player[i] == player[winner]) winners++;
}
if (winners > 1) MessageBox.Show("Remíza", "Pexeso info", MessageBoxButtons.OK, MessageBoxIcon.Information);
else
{
int winner_num = winner + 1;
string msg = string.Format("Vítězem je hráč {0} se ziskem {1} bodů", winner_num, player[winner]);
MessageBox.Show(msg, "Pexeso info", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
else //pokud jsou ještě nějaké neotočené karty
{
if (click_on_stop) playing = false;
else
{
if (player_ai[current_player]) ClickOn(NextRandom(last_index)); //pokud aktuálně hraje počítač, tak otočí nějakou kartu
}
}
}
}
private int? CardFromMemory() //<--
{
foreach(int i in memory)
{
if (i != last_index && cards[i].enabled && cards[i].picture == cards[last_index].picture) return i;
}
return null;
}
/// <summary>
/// výběr náhodné karty (pro AI)
/// </summary>
/// <param name="ignore">index již otočené karty</param>
/// <returns></returns>
private int NextRandom(int ignore)
{
Application.DoEvents();
if(IQ > 0 && click_count > 0) //<--
{
int? i = CardFromMemory();
if (i.HasValue) return i.Value;
}
int r;
while (true)
{
r = random.Next(0, 20);
if (r != ignore && cards[r].covered && cards[r].enabled) return r;
}
}
/// <summary>
/// přepnout hráče
/// </summary>
private void NextPlayer()
{
current_player++;
if (current_player == players_count) current_player = 0;
switch (current_player)
{
case 0:
{
laPlayer1.ForeColor = Color.YellowGreen;
laPlayer2.ForeColor = Color.Gray;
laPlayer3.ForeColor = Color.Gray;
laPlayer4.ForeColor = Color.Gray;
break;
}
case 1:
{
laPlayer1.ForeColor = Color.Gray;
laPlayer2.ForeColor = Color.YellowGreen;
laPlayer3.ForeColor = Color.Gray;
laPlayer4.ForeColor = Color.Gray;
break;
}
case 2:
{
laPlayer1.ForeColor = Color.Gray;
laPlayer2.ForeColor = Color.Gray;
laPlayer3.ForeColor = Color.YellowGreen;
laPlayer4.ForeColor = Color.Gray;
break;
}
case 3:
{
laPlayer1.ForeColor = Color.Gray;
laPlayer2.ForeColor = Color.Gray;
laPlayer3.ForeColor = Color.Gray;
laPlayer4.ForeColor = Color.YellowGreen;
break;
}
}
Refresh();
}
// čas
private void GameTimer_Tick(object sender, EventArgs e)
{
if (sec == 59)
{
min++;
sec = 0;
}
else sec++;
laTime.Text = string.Format("{0}:{1:00}", min, sec);
}
/// <summary>
/// nová hra
/// </summary>
private void StartNewGame(int pcount)
{
IQ = Convert.ToInt32(nuLevel.Value);
//vynulování všeho:
click_on_stop = true;
playing = true;
last_index = -1;
player[0] = 0; //bodovy stav
player[1] = 0; //bodovy stav
player[2] = 0; //bodovy stav
player[3] = 0; //bodovy stav
player_ai[0] = ai1.Checked; //má hrát pc?
player_ai[1] = ai2.Checked; //má hrát pc?
player_ai[2] = ai3.Checked; //má hrát pc?
player_ai[3] = ai4.Checked; //má hrát pc?
click_count = 0;
completed = 0;
players_count = pcount;
current_player = pcount - 1; //nastavíme na posledního hráče, aby to skočilo v NextPlayer() na 1. hráče
NextPlayer(); // je to tu kvůli vybarvení labelů
min = 0; //minuty hry
sec = 0; //sekundy hry
memory.Clear(); // <--
//vytvořím pole všech čísel obrázků po dvou (1,1,2,2,3,3...)
List<int> idx = new List<int>();
for (int i = 1; i < 11; i++)
{
idx.Add(i);
idx.Add(i);
}
//náhodně povybírám čísla z pole
for (int i = 0; i < 20; i++)
{
int u = random.Next(0, idx.Count);
cards[i].picture = idx[u];
cards[i].enabled = true;
cards[i].covered = true;
idx.RemoveAt(u);
}
//překreslím plátno a vynuluji stav:
Canvas.Refresh();
laTime.Text = "0:00";
laPlayer1.Text = "0";
laPlayer2.Text = "0";
laPlayer3.Text = "0";
laPlayer4.Text = "0";
GameTimer.Start();
click_on_stop = false;
if (player_ai[current_player]) ClickOn(NextRandom(last_index)); //pokud začíná pc..
}
private void btPlay_Click(object sender, EventArgs e)
{
if (playing) StopGame();
int cnt = Convert.ToInt32(nuCount.Value);
nuCount.Focus();
StartNewGame(cnt);
}
private void btStop_Click(object sender, EventArgs e)
{
if (playing) StopGame(); //zastavení hry je takové jakési nedodělané, ale nechci to dělat moc složité
nuCount.Focus(); //jen pro deaktivaci tlačítka
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
StopGame();
}
}
struct Card
{
public int picture; // index obrázku karty
public bool enabled; // možnost otočení karty
public bool covered; // true: karta je otočena obrázkem dolů, false: karta je otočena obrázkem nahorů
}
}