Avatar billede hclarsen Nybegynder
09. april 2006 - 17:08 Der er 23 kommentarer og
1 løsning

Kode og forklaring

Hej alle - hvad gør følgende kode helt præcist?

procedure board;
var
i, j, k: integer;
begin
  for i := 1 to 3 do
  begin
    for j := 1 to 3 do
    begin
      k:= (i - 1) * 3 + j - 1;
      x_position[y, j] := 0;
    y_position[i][j] := 0;
    end;
  end;

I og j antager jo bare nogle værdier mellem 1 og 3, og k er jo et tal mellem 0 og 8, men hvad med den sidste del? x_position og y_position er arrays som i [1..3,1..3]
09. april 2006 - 17:13 #1
k:= (i - 1) * 3 + j - 1;
Laver ingenting, den trækker blot tiden ud.

Derudover fylder den matrixerne x_position og y_position med nuller.
Avatar billede hclarsen Nybegynder
09. april 2006 - 17:15 #2
Åh ok, hvad er forskellen på [i,j] og [i][j]?
09. april 2006 - 17:20 #3
Ingenting.
Avatar billede hclarsen Nybegynder
09. april 2006 - 17:27 #4
Når jeg skriver TLabel(Sender).caption - er der så tale om den aktuelle label, hvori koden står?

Og når man skriver 'exit', hvad gør dette så? Hopper den bare linien over, eller hvorledes?
Avatar billede arne_v Ekspert
09. april 2006 - 17:41 #5
den beregning af k ligner noget der bruges til at omregne mellem et 2 dimensionelt
array og et 1 dimensionelt array

men anton_kruse har helt ret i at det ikke bruges i den postede kode
Avatar billede hclarsen Nybegynder
09. april 2006 - 18:59 #6
Hvad med denne kode? Jeg kan fortælle, at den checker, om der er vundet når man spiller kryds og bolle, men jeg kan ikke helt se, hvorledes det virker:

function vundetellerej(iPos: 3x3): integer; //3x3 er en matrix
var
iScore : Integer;
i : Integer;
j : Integer;
begin
Result := -1;

//in rows?
iScore := 0;
for i := 1 to 3 do
begin
  iScore := 0;
  Inc(Result);
  for j := 1 To 3 do Inc(iScore, iPos[i,j]);
  if iScore = 3 Then Exit
end;//for i

//top-left bottom-right diagonal?
iScore := 0;
Inc(Result);
for i := 1 to 3 do Inc(iScore, iPos[i,i]);
if iScore = 3 then Exit;

//top-right bottom-left diagonal?
iScore := 0;
Inc(Result);
for i := 1 to 3 do Inc(iScore, iPos[i,4-i]);
if iScore = 3 then Exit;

//columns?
for i := 1 to 3 do
begin
  iScore := 0;
  Inc(Result);
  for j := 1 to 3 do Inc(iScore, iPos[j,i]);
  if iScore = 3 then Exit;
end;//for i

Result := -1;
end;

Jeg forstår ikke, hvorledes den kan afgøre det, ved blot at forøge de forskellige tal?
Avatar billede hclarsen Nybegynder
09. april 2006 - 20:09 #7
Vedlægger gerne flere point
Avatar billede nielle Nybegynder
09. april 2006 - 20:26 #8
Jeg gætter på at den holder styr på X-og-O brættet ved at have et -1 eller et +1 i hver celle alt efter om der er et 'X', eller et 'O'. Og så i øvrigt 0 i de celler hvor der ikke er noget.

Hvis dette er rigtigt, kan den viste kode finde ud af om der er en række med 3 O'er:

Den tæller simpelthen summen (værdien i iScore) af hver af de 3 rækker, derefter summen af den ene diagonal og summen af den anden, og så til sidst summen af hver af de tre søjler. Hvis summen i blot en af disse er '3', svarende til 3 1-taller, så er der en række (og proceduren exit'er).

Koden kan altså beregne om der er en række med 3 O'er. Der må være noget tilsvarende kode som vurdere på 3 X-er, eller også er der noget kode et eller andet stede, som vender fortegnet på alle værdierne i matricen før at funktionen vundetellerej() kaldes.
Avatar billede hclarsen Nybegynder
09. april 2006 - 20:32 #9
ahh ok, men hvad er der så med result? Den er jo både lig -1 først og til sidst?
Avatar billede nielle Nybegynder
09. april 2006 - 20:43 #10
Nej Result er 0 eller over hvis proceduren afsluttes via en af Exit'erne. Hvis den får lov til at løve til sin ende sættes Result derimod til -1 igen.
Avatar billede hclarsen Nybegynder
09. april 2006 - 20:55 #11
Ok, jeg kan faktisk godt se det nu. Jeg har dog et problem - jeg kan sagtens se, at den checker de forskellige steder i matrixen, men der står jo ikke rigtig, hvad den checker for?
Avatar billede nielle Nybegynder
09. april 2006 - 21:04 #12
Nej, det kan man ikke se ud fra den viste kode.

Men den tjekker som sagt for om det er 3 1-tallere der står i macticens rækker, diagonaler eller søjler. Så du må kunne gætte svaret ved at finde ud af om det er X eller O som repræsenteres med værdien 1.
Avatar billede hclarsen Nybegynder
09. april 2006 - 21:09 #13
hvor ser du, at det er et-taller? Det er jo kun et taller første gang i "for i to 3 do"
Avatar billede nielle Nybegynder
09. april 2006 - 21:22 #14
Det "ser" jeg af sådan noget kode som dette:

    for j := 1 To 3 do Inc(iScore, iPos[i,j]);
    if iScore = 3 Then Exit

Functionen Inc tæller iScore op med værdien fra iPos[i,j]. For-løkken sikre at dette sker 3 gange. I linje nr. 2 testes der om iScore er lig 3. Tilsammen giver de kun mening hvis det er 3 1-taller som giver "det rigtige svar".

Jeg indrømmer at en talrækkefølge som f.eks. 4, 5, -6 også ville giove summen 3, men det gover ikke helt mening i sammenhængen (et X-og-O spil) at der skulle stå det.
Avatar billede hclarsen Nybegynder
09. april 2006 - 22:47 #15
Jeg har noget mere uforståelig (i mine øjne) kode, men alligevel har jeg nogle forslag til, hvordan det skal kunne forstås:

function TfrMain.GamePlay(xo_Move : Integer):integer;
var
x, y : 1..3;
iWin : integer;
begin
Result := -1;

Inc(iMove);
x := (xo_Move Div 3) + 1;
y := (xo_Move Mod 3) + 1;

if sPlaySign = 'O' then
begin
  iOPos[x,y] := 1;              // hvorfor skal den sættes lig 1?
  iWin := CheckWin(iOPos);      // her tjekker den jo bare om der er gevinst
end
else
begin
  iXPos[x,y] := 1;              // .. gør det samme for spiller-X
  iWin := CheckWin(iXPos);
end;

TLabel(FindComponent('lblCell' + IntToStr(xo_Move))).Caption := sPlaySign;

Result := iWin;

if iWin >= 0 then
begin
  bGameOver := True;
end;
Avatar billede nielle Nybegynder
09. april 2006 - 23:12 #16
Ahh, programmet bruger *2* forskellige matricer, iOPos og iXPos, som viser hvor hhv O'erne og X'erne er placeret på brættet. Hvis der står et 1-tal på en plads så er det hhv. et O eller et X - og hvis der står 0 er der *ikke* et O eller et X (men der kan være en "modstander-brik").

Bemærk: Dette er ikke noget vildt gennemtænkt design: f.eks. kan der nu - i princippet - være både et O og et X på en og samme plads!

Koden:

    x := (xo_Move Div 3) + 1;
    y := (xo_Move Mod 3) + 1;

omregner fra en værdi 0-8 til en x- og y-position på brættet; Det er faktisk kode som svare til arne_v's bemærkning ang. k i 09/04-2006 17:41:02.

Variablen sPlaySign indeholder enten et 'O' eller noget andet (sandsynligvis et 'X' men det er ikke helt sikkert). Koden:

    if sPlaySign = 'O' then
    begin
        iOPos[x,y] := 1;              // hvorfor skal den sættes lig 1?
        iWin := CheckWin(iOPos);      // her tjekker den jo bare om der er gevinst
    end
    else
    begin
        iXPos[x,y] := 1;              // .. gør det samme for spiller-X
        iWin := CheckWin(iXPos);
    end;

indsætter et 1-tal på x,y positionen i den rigtige rigtige matrix: i iOPos hvis det er et 'O' og i iXPos ellers (hvis det er et 'X').

Derefter kaldes CheckWin() med den relevante matrix for at se om den ene eller den anden spiller har vundet. Hvis der er en vinder sættes bGameOver til True.
Avatar billede hclarsen Nybegynder
09. april 2006 - 23:23 #17
Herligt, nu forstår jeg det. Jeg har bare et sidste spørgsmål, og så så jeg meget gerne, at du lagde et velfortjent svar.

Hvorfor er det ikke muligt for mig, at skrive følgende?

function goddag(positioner: array [1..3, 1..3] of integer): integer;
Avatar billede nielle Nybegynder
09. april 2006 - 23:36 #18
Desværre er mit Pascal en smule rustent så jeg skal ikke lige kunne udtale mig om grunden.

Men du kan jo - i toppen - af din kode - lave en type erklæring:

    type

        TTicTacToeBoard = array [1..3, 1..3] of integer;  // Tic-Tac-Toe er engelsk for X-og-O.

og så definere din funktion sådan:

    function goddag(positioner: TTicTacToeBoard): integer;
Avatar billede arne_v Ekspert
10. april 2006 - 00:09 #19
det er den rigtige Pascal løsning
Avatar billede nielle Nybegynder
11. april 2006 - 14:53 #20
Jeg går ud fra at du har fået det til at virke?
Avatar billede hclarsen Nybegynder
11. april 2006 - 20:27 #21
Det kan du tro - mange tak
Avatar billede nielle Nybegynder
11. april 2006 - 22:35 #22
Nu gav du dem jo alle sammen til mig, og det er da ikke helt fair mod anton_kruse_andersen. Værsgod:

http://www.eksperten.dk/spm/702282
Avatar billede hclarsen Nybegynder
14. april 2006 - 13:05 #23
Jeg tænkte på - følgende kode:

function vundetellerej(iPos: 3x3): integer; //3x3 er en matrix
var
iScore : Integer;
i : Integer;
j : Integer;
begin
Result := -1;

//in rows?
iScore := 0;
for i := 1 to 3 do
begin
  iScore := 0;
  Inc(Result);
  for j := 1 To 3 do Inc(iScore, iPos[i,j]);
  if iScore = 3 Then Exit
end;//for i

//top-left bottom-right diagonal?
iScore := 0;
Inc(Result);
for i := 1 to 3 do Inc(iScore, iPos[i,i]);
if iScore = 3 then Exit;

//top-right bottom-left diagonal?
iScore := 0;
Inc(Result);
for i := 1 to 3 do Inc(iScore, iPos[i,4-i]);
if iScore = 3 then Exit;

//columns?
for i := 1 to 3 do
begin
  iScore := 0;
  Inc(Result);
  for j := 1 to 3 do Inc(iScore, iPos[j,i]);
  if iScore = 3 then Exit;
end;//for i

Result := -1;
end;


Den er blevet gennemgået, men jeg har flere spørgsmål. Vil det sige, at hvis der ikke er tre ens i nogle af tabellerne, så bliver iScore lig 11? Og hvilken værdi antager result alt efter, hvilken række/linie der er tre ens i?
Avatar billede nielle Nybegynder
14. april 2006 - 21:48 #24
iScore bliver med jævne mellemrum sat lig med 0, så nej den vil aldrig komme op på 11. Faktisk exit'er proceduren jo oven i købet hvis den bliver lig 3.

Forklaring på resten af koden:


function vundetellerej(iPos: 3x3): integer; //3x3 er en matrix
var
    iScore : Integer;
    i : Integer;
    j : Integer;
begin
    Result := -1;  // Result starter med at være -1

    // Denne kodeblok undersøger om der er 3 0'er i en af rækkerne

    //in rows?
    iScore := 0;  // iScore sættes til 0. Dette er overføldigt, for det gør den også inde i løkken.
    for i := 1 to 3 do  // Gennemløb hver af de 3 rækker.
    begin
        iScore := 0;  // iScore sættes til 0.
        Inc(Result);  // Result tælles 1 op: værdi=0 ved 1. række, 1 ved 2. og 2 ved 3. række.
        for j := 1 To 3 do Inc(iScore, iPos[i,j]);  // Der lægges 1 til iScore for hvert O i den aktuelle række.
        if iScore = 3 Then Exit  // Hvis der var 3 O'er i rækken exit'es.
    end;//for i

    // Denne kodeblok undersøger diagonalen fra øverste venstre hjørne til nederste højre.
    // NB: På dette sted i koden er Result lig med 2.

    //top-left bottom-right diagonal?
    iScore := 0;  // iScore sættes igen til 0.
    Inc(Result);  // Result tælles 1 op; den er nu lig 3.
    for i := 1 to 3 do Inc(iScore, iPos[i,i]);  // Der lægges 1 til iScore for hvert O i diagonalen.
    if iScore = 3 then Exit;  // Hvis der var 3 O'er i diagonalen exit'es.

    // Denne kodeblok undersøger diagonalen fra nederste venstre hjørne til øverste højre.
    // NB: På dette sted i koden er Result lig med 3.

    //top-right bottom-left diagonal?
    iScore := 0;  // iScore nulstilles igen.
    Inc(Result);  // Result tælles 1 op; ny værdi 4.
    for i := 1 to 3 do Inc(iScore, iPos[i,4-i]);  // Der lægges 1 til iScore for hver O i diagonalen.
    if iScore = 3 then Exit;  // Hvis der var 3 O'er i diagonalen exit'es.

    // Den sidste kodeblok undersøger om der er 3 O'er i en af søjlerne.
    // NB: På dette sted i koden er Result lig med 4.

    //columns?
    // Denne gang glemmer programøren at nulstille iScore - men det er jo heller ikke nødvendigt.
    for i := 1 to 3 do  // Gennemløb hver af de 3 søjler.
    begin
        iScore := 0;  // iScore nulstilles for hver søjle.
        Inc(Result);  // Result tælles 1 op for hver søjle. Værdierne 5, 6 og 7.
        for j := 1 to 3 do Inc(iScore, iPos[j,i]);  //Der lægges 1 til for hver O i den aktuelle søjle.
        if iScore = 3 then Exit;  // Hvis der var 3 O'er i søjlen exit'es.
    end;//for i

    // Hvis der ikke er exit'et på dette tidspunkt, så må det betyde at der hverken
    // var en række, en diagonal, eller en række O'er et eller andet sted.

    Result := -1;
end;


Hvis funktionen vundetellerej() returnere et .1 var der altså ikke nogen række. Hvsi det govere en af værdierne 0..7 kan man ud af denne se hvor det var at de 3 ens var henne (hvis man gider det):

0 : 1. række,
1 : 2. række,
2 : 3. række,
3 : Diagonalen fra øverste venstre hjørne til nederste højre,
4 : Diagonalen fra nederste venstre hjørne til øverste højre,
5 : 1. søjle,
6 : 2. søjle, og
7 : 3. søjle
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester