Wątek przeniesiony 2016-02-01 18:04 z Newbie przez furious programming.

W jaki sposób zrobić grę Kółko i krzyżyk?

0

Oto mój kod powstał pod wpływem natchnienia... Wrzućcie 9 przycisków na formę i przypiszcie zdarzenia:

unit code;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm3 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Button5: TButton;
    Button6: TButton;
    Button7: TButton;
    Button8: TButton;
    Button9: TButton;
    Button10: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure Button7Click(Sender: TObject);
    procedure Button8Click(Sender: TObject);
    procedure Button9Click(Sender: TObject);
    procedure Button10Click(Sender: TObject);
  private
    { Private declarations }
  public
  procedure SprawdzStan;
  function KrzyzykVictoria: Boolean;
  function Kolkovictoria: Boolean;
  procedure NoweRozdanie;
    { Public declarations }
  end;

var
  Form3: TForm3;
  Table: array [1..9] of byte = (0,0,0,0,0,0,0,0,0);
  // tablica stanów:
  {
  0 - bez napisu
  1: - kółko
  2: - krzyżyk
  }


  Gracz: Integer = 0; //gracz 1 - kółko, 0 - krzyżyk

implementation

{$R *.dfm}

procedure TForm3.Button10Click(Sender: TObject);
begin
button10.Enabled := False;
If Application.MessageBox(':-) nowe rozdanie?','Kółko i krzyżyk',MB_IconInformation or MB_YESNO) = ID_YES then

NoweRozdanie;

Button10.Enabled := True;

end;

procedure TForm3.Button1Click(Sender: TObject);
begin

if Button1.Caption <> '' then exit;


case Gracz of
0: begin button1.Caption := 'x'; Table[1] := 2; sprawdzStan; gracz := 1; button1.Enabled := False; end;
1: begin button1.Caption := 'o'; Table[1] := 1; sprawdzStan; gracz := 0; button1.Enabled := False; end;
end;

end;

procedure TForm3.Button2Click(Sender: TObject);
begin
if Button2.Caption <> '' then exit;


case Gracz of
0: begin button2.Caption := 'x'; Table[2] := 2; sprawdzStan; gracz := 1; button2.Enabled := False; end;
1: begin button2.Caption := 'o'; Table[2] := 1; sprawdzStan; gracz := 0; button2.Enabled := False; end;
end;


end;

procedure TForm3.Button3Click(Sender: TObject);
begin
if Button3.Caption <> '' then exit;


case Gracz of
0: begin button3.Caption := 'x'; Table[3] := 2; sprawdzStan; gracz := 1; button3.Enabled := False; end;
1: begin button3.Caption := 'o'; Table[3] := 1; sprawdzStan; gracz := 0; button3.Enabled := False; end;
end;

end;

procedure TForm3.Button4Click(Sender: TObject);
begin
if Button4.Caption <> '' then exit;


case Gracz of
0: begin button4.Caption := 'x'; Table[4] := 2; sprawdzStan; gracz := 1; button4.Enabled := False; end;
1: begin button4.Caption := 'o'; Table[4] := 1; sprawdzStan; gracz := 0; button4.Enabled := False; end;
end;

end;

procedure TForm3.Button5Click(Sender: TObject);
begin
if Button5.Caption <> '' then exit;


case Gracz of
0: begin button5.Caption := 'x'; Table[5] := 2; sprawdzStan; gracz := 1; button5.Enabled := False; end;
1: begin button5.Caption := 'o'; Table[5] := 1; sprawdzStan; gracz := 0; button5.Enabled := False; end;
end;

end;

procedure TForm3.Button6Click(Sender: TObject);
begin
if Button6.Caption <> '' then exit;


case Gracz of
0: begin button6.Caption := 'x'; Table[6] := 2; sprawdzStan; gracz := 1; button6.Enabled := False; end;
1: begin button6.Caption := 'o'; Table[6] := 1; sprawdzStan; gracz := 0; button6.Enabled := False; end;
end;

end;

procedure TForm3.Button7Click(Sender: TObject);
begin
if Button7.Caption <> '' then exit;


case Gracz of
0: begin button7.Caption := 'x'; Table[7] := 2; sprawdzStan; gracz := 1; button7.Enabled := False; end;
1: begin button7.Caption := 'o'; Table[7] := 1; sprawdzStan; gracz := 0; button7.Enabled := False; end;
end;

end;

procedure TForm3.Button8Click(Sender: TObject);
begin
if Button8.Caption <> '' then exit;


case Gracz of
0: begin button8.Caption := 'x'; Table[8] := 2; sprawdzStan; gracz := 1; button8.Enabled := False; end;
1: begin button8.Caption := 'o'; Table[8] := 1; sprawdzStan; gracz := 0; button8.Enabled := False; end;
end;

end;

procedure TForm3.Button9Click(Sender: TObject);
begin
if Button9.Caption <> '' then exit;


case Gracz of
0: begin button9.Caption := 'x'; Table[9] := 2; sprawdzStan; gracz := 1; button9.Enabled := False; end;
1: begin button9.Caption := 'o'; Table[9] := 1; sprawdzStan; gracz := 0; button9.Enabled := False; end;
end;

end;

procedure TForm3.NoweRozdanie;
begin
Button1.Caption := '';
Button2.Caption := '';
Button3.Caption := '';
Button4.Caption := '';
Button5.Caption := '';
Button6.Caption := '';
Button7.Caption := '';
Button8.Caption := '';
Button9.Caption := '';

Table[1] := 0;
Table[2] := 0;
Table[3] := 0;
Table[4] := 0;
Table[5] := 0;
Table[6] := 0;
Table[7] := 0;
Table[8] := 0;
Table[9] := 0;


Gracz := 1;

Button1.Enabled := True;
Button2.Enabled := True;
Button3.Enabled := True;
Button4.Enabled := True;
Button5.Enabled := True;
Button6.Enabled := True;
Button7.Enabled := True;
Button8.Enabled := True;
Button9.Enabled := True;

end;

procedure TForm3.SprawdzStan;
begin

{ KRZYŻYK }

// krzyzyk w poziomie
if (Table[1] = 2) and (Table[2] = 2) and (Table[3] = 2) then KrzyzykVictoria;
if (Table[4] = 2) and (Table[5] = 2) and (Table[6] = 2) then KrzyzykVictoria;
if (Table[7] = 2) and (Table[8] = 2) and (Table[9] = 2) then KrzyzykVictoria;

// krzyżyk w pionie
if (Table[1] = 2) and (Table[4] = 2) and (Table[7] = 2) then KrzyzykVictoria;
if (Table[2] = 2) and (Table[5] = 2) and (Table[8] = 2) then KrzyzykVictoria;
if (Table[3] = 2) and (Table[6] = 2) and (Table[9] = 2) then KrzyzykVictoria;

// krzyżyk po skosie
if (Table[1] = 2) and (Table[5] = 2) and (Table[9] = 2) then KrzyzykVictoria;
if (Table[7] = 2) and (Table[5] = 2) and (Table[3] = 2) then KrzyzykVictoria;

{ KÓŁKO}

// kółko w poziomie
if (Table[1] = 1) and (Table[2] = 1) and (Table[3] = 1) then KolkoVictoria;
if (Table[4] = 1) and (Table[5] = 1) and (Table[6] = 1) then KolkoVictoria;
if (Table[7] = 1) and (Table[8] = 1) and (Table[9] = 1) then KolkoVictoria;

// kółko w pionie
if (Table[1] = 1) and (Table[4] = 1) and (Table[7] = 1) then KolkoVictoria;
if (Table[2] = 1) and (Table[5] = 1) and (Table[8] = 1) then KolkoVictoria;
if (Table[3] = 1) and (Table[6] = 1) and (Table[9] = 1) then KolkoVictoria;

// kółko po skosie
if (Table[1] = 1) and (Table[5] = 1) and (Table[9] = 1) then KolkoVictoria;
if (Table[7] = 1) and (Table[5] = 1) and (Table[3] = 1) then KolkoVictoria;


end;

function TForm3.Kolkovictoria: Boolean;
begin
If Application.MessageBox('Wygrało kółko o :-) nowe rozdanie?','Kółko i krzyżyk',MB_IconInformation or MB_YESNO) = ID_YES then

NoweRozdanie;

Result := True;

end;

function TForm3.KrzyzykVictoria: Boolean;
begin
If Application.MessageBox('Wygrał krzyżyk x :-) nowe rozdanie?','Kółko i krzyżyk',MB_IconInformation or MB_YESNO) = ID_YES then

NoweRozdanie;

Result := True;
end;

end.
3
  • w kółko się powtarzasz - to trzeba zmienić,
  • nie używasz Else w kluczowych miejscach, a to błąd i marnowanie czasu,
  • macierz przechowująca stan planszy może wyglądać czytelniej:
type
  TFieldKind  = (fkEmpty, fkCircle, fkCross);
  TBoardState = array [0 .. 8] of TFieldKind;
  • identyfikator gracza powinien być wartością logiczną - graczy jest dwóch, więc dwa stany wystarczą; Zmiana gracza to zanegowanie bieżącego stanu (np. boolPlayer := not boolPlayer),
  • wszystkie przyciski (TButton) powinny wylądować w jakiejś macierzy, np. jako pole klasy okna,
  • używasz polskich identyfikatorów - kod do kosza,
  • słabe formatowanie kodu (zapomniałem dodać),
  • brak źródeł, czyli nikt nie przetestuje,
  • wątek wygląda jak prośba o ocenę, więc posyłam do odpowiedniego działu.
6

po co mi else jak kod działa bez problemu..............

Po to, że możliwy do spełnienia warunek jest tylko jeden, a Twój kod sprawdzi wszystkie warunki, nawet jeśli pierwszy zostanie spełniony; To są podstawy programowania, których jak widać nie ogarniasz;

to że Tobie się nie podoba nie oznacza że jest do d**y skoro gra działa...

Bo ten kod jest z d**y - jest nieoptymalny, o 70% za długi, beznadziejnie formatowany i na dodatek z jakimiś głupimi pół-polskimi identyfikatorami typu KolkoVictoria; Kompletnie nie stosujesz się do przyjętej konwencji nazewnictwa; A gdyby trzeba było powiększyć planszę z 3x3 na 5x5, to Twoja drabinka **If**ów sięgnęła by stąd do Korei Północnej; Najważniejsze uchybienia i słabe punkty zapisane są w punktach w powyższym poście, a znajdzie się ich więcej;

Ledwie liznąłeś programowanie w Delphi, a już wydaje Ci się, że wszystkie rozumy pozjadałeś, przedstawiając wyssane z nosa argumenty typu "przecież działa"; I co z tego że działa - kod jest bardzo słabej jakości i jest go o wiele za dużo; Więc go popraw, zamiast rzucać się do gardła.

0

Na szybko sprawdziłem to w Lazarusie (prosta formatka z 10-coma przyciskami Button1...Button10). W kodzie jest błąd! Po zakończeniu gry jak wygra kółko albo krzyżyk i zapyta o nowe rozdanie, ostatni kliknięty przycisk pozostaje wyłączony. Stosunkowo łatwo po tym kodzie dojść dlaczego. Tylko przy kliknięciu Button10 jest OK.

@xor01

Musi minąć sporo czasu (naprawdę sporo) zanim to co napiszesz będzie chciał ktoś inny używać :-) Generalnie cokolwiek byś nie wrzucił to każdy się w sumie przyczepi :-) Właściwie to każdy zaczynał tak samo i na początku zawsze kod jest do bani.

Udało się napisać kółko i krzyżyk? Spoko. Napisz jeszcze żeby drugim playerem był komputer z którym przez nieuwagę przegrasz :-)

4

@xor01
nuke.jpg
oczy.png

Skoro ten kod jest taki dobry to zrób małą modyfikacje:

  • niech rozmiar planszy będzie zadany za pomocą parametrów N i M przez użytkownika przy starcie (powiedzmy w zakresie od 2 do miliona)
  • niech liczba wygrywających symboli obok siebie będzie zadana parametrem K podanym przez użytkownika podczas startu (tak samo od 2 do miliona)
  • niech liczba symboli (a ty samym graczy) będzie zadana parametrem przy starcie w zakresie powiedzmy 2-50

I teraz pytanie: czy nadal napisał byś ten kod w ten sam sposób?

0

Kurna, gdzieś widziałem kiedyś kod, w którym gościu ręcznie zbudował tablicę **ze wszystkimi kombinacjami **i porównywał ;)

0

Można w przypadku tej gry dodać jako drugiego gracza po prostu komputer według prostego algorytmu który bada co będzie w następnym ruchu tj:

  1. najpierw próbuje obstawiać pola tak żeby wygrać
  2. jeśli nie to tak żeby zablokować możliwość wygrania przez przeciwnika
  3. w ostateczności obstawić określone pola

Tu jest pythonowa gra z komputerem:
https://inventwithpython.com/chapter10.html

I życzę powodzenia jak ktoś myśli że tak łatwo może wygrać.

0
def isWinner(bo, le):
# Given a board and a player’s letter, this function returns True if that player has won.
# We use bo instead of board and le instead of letter so we don’t have to type as much.
return ((bo[7] == le and bo[8] == le and bo[9] == le) or # across the top
(bo[4] == le and bo[5] == le and bo[6] == le) or # across the middle
(bo[1] == le and bo[2] == le and bo[3] == le) or # across the bottom
(bo[7] == le and bo[4] == le and bo[1] == le) or # down the left side
(bo[8] == le and bo[5] == le and bo[2] == le) or # down the middle
(bo[9] == le and bo[6] == le and bo[3] == le) or # down the right side
(bo[7] == le and bo[5] == le and bo[3] == le) or # diagonal
(bo[9] == le and bo[5] == le and bo[1] == le)) # diagonal

@drorat1 - to taka sama tragedia jak kod od OP... :]

0

jaki to ma związek z Object Pascalem?? ;d

Tyle, co Twój kod, czyli nic <3

http://rosettacode.org/wiki/Tic-tac-toe -- Już kod w Befunge czyta się lepiej.
Co ciekawe, te kody też są słabej jakości - nawet w Haskellu HLint by się przyczepił na pewno, już nie mówiąc o doświadczonym programiście. Ktoś znalazł jakieś dobre źródła, żeby pokazać @xor01, jak to powinno wyglądać?

0
merlinnot napisał(a):

Ktoś znalazł jakieś dobre źródła, żeby pokazać @xor01, jak to powinno wyglądać?

Ten przykład w pythonie podałem tylko po to żeby dać @xor01 nieco do myślenia, sama gra player-player bez możliwości grania z komputerem robi małe wrażenie. Co do kodu, mniej więcej w ten sposób:

http://www.danieleteti.it/a-simple-start-with-mvp-in-delphi-for-win32-part-2/

Passive View a konkretniej wzorzec Model-View-Presenter, oczywiście z testami a co do gry, należałoby to oprzeć o jakiś silnik, i to w taki sposób żeby można było grać z komputerem albo z drugim graczem. Dla @xor01 sporo nauki żeby napisać w taki sposób :-)

0

To jak napisać całą grę nie jest jakoś szczególnie ważne, dlatego że można zrobić to dobrze na wiele sposobów; Natomiast kluczowy w tej grze jest algorytm walidujący stan planszy po każdym ruchu (obojętne kogo - czy gracza, czy komputera); IMHO jest kluczowy, bo powinien być minimalistyczny i uniwersalny, bez hardkodowanych drabinek warunków i rozmiarów planszy;

Wiadome, że uniwersalny algorytm będzie dłuższy niż te drabinki **If**ów, ale wzamian za to będzie można grę napisać tak, aby gracz mógł sobie wybrać rozmiar planszy oraz liczbę symboli dających wygraną (będzie mógł grać w klasyczne Kółko i Krzyżyk lub zwiększyć wspomniane wartości i grać w Pięć Kamieni);

Mam przed sobą ~30h klepania kodu komponentów, jednak jeśli znajdę z godzinkę to postaram się wrzucić tutaj przynajmniej zestaw funkcji walidujących, żeby rozwiać wszelkie wątpliwości, jeśli o tę część gry chodzi.

0

Nie wiem czy ktoś pisał, ale ja jak tworzyłem tic tac toe to użyłem

1 użytkowników online, w tym zalogowanych: 0, gości: 1