Avatar billede jespertk Nybegynder
15. juni 1999 - 11:11 Der er 9 kommentarer og
1 løsning

Find fem fejl

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Timer2: TTimer;
    ListBox1: TListBox;
    MainMenu1: TMainMenu;
    Options1: TMenuItem;
    Nytspil1: TMenuItem;
    Quit1: TMenuItem;
    About1: TMenuItem;
    Marker: TTimer;
    Afbryd1: TMenuItem;
    Trkforslag1: TMenuItem;
    ListBox2: TListBox;
    procedure FormPaint(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Timer1Timer(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
    procedure Options1Click(Sender: TObject);
    procedure Nytspil1Click(Sender: TObject);
    procedure Quit1Click(Sender: TObject);
    procedure About1Click(Sender: TObject);
    procedure MarkerTimer(Sender: TObject);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure Afbryd1Click(Sender: TObject);
    procedure Trkforslag1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
  Procedure SetDefaultOptions;
  Procedure PrepareField;
  Procedure NewGame;
  Function CPUvsCPU:Boolean;
  Procedure CreateValueList;
  Procedure GetValueList;
  Procedure SaveSettings;
  Function Min(A,B:Integer):Integer;
  Function Max(A,B:Integer):Integer;

Const
DefSettingsName=''4PaaStribe-DefaultSettings.DS'';
StdSizes:Array[0..4] of TPoint=//Benyttes i form2
  ((X:7; Y:6),(X:7; Y:6),(X:6; Y:5),(X:9; Y:7),(X:12; Y:10));
DefaultBlink=6;//skal være lige (tænd/sluk)
MaxRekLevel=20;
BegynderenTabte=2;
IngenVinder=3;
BegynderenVandt=4;
KunX=240;//Pos and KunX
KunY=15;//Pos and KunY
IsDebugging=True;
TomOrCP:Integer=3;
Farver:Array[0..5] of Integer=(ClBlue,ClGreen,ClYellow,ClWhite,ClRed,ClBlack);
//Størrelser på spillepladen...
Ln2MaxSize=4;
PPMaxSize=14;
PMaxSize=15;
MaxSize=16;
SMaxSize=17;
PMaxSize4=60;
MaxSize4=64;
SMaxSize4=68;
SqrPPMaxS=196;
PSqrMaxS=255;
//Player types
Menneske=0;
CPULNem=1;
CPUNem=2;
CPUMiddel=3;
CPUHalvSvaer=4;
CPUSvaer=5;
CPULangsom=6;
//Værdier til celle...
Udenfor:Integer=0;
Tom:Integer=1;
FriTom:Integer=3;
Pl1:Integer=2;
SelfPl:Integer=2;
Pl2:Integer=4;
//$1 Computerens intelligens er baseret på 9 konstanter...
SimpleTrap:Integer=$4000;
Save4S=$200000;    LSave4S=$100000;
Prevent4S=$40000;  LPrevent4S=$20000;
SaveTrap=$8000;    LSaveTrap=$4000;
PreventTrap=$1000; LPreventTrap=$800;
//Hvis fx Værdi>LSave4S er der med SIKKERHED mulighed for 4 på stribe.
MaxOrdValue=$7FF;//Value and OrdMaxValue=SaveTrap,PreventTrap, osv. siet fra
Straight:Array[5..8] of Integer=(Save4S+150,Save4S+170,Save4S+190,Save4S+210);
Values:Array[1..3,0..3] of Integer=((60,49,0,0),(40,0,90,55),(20,0,0,35));
  //0:umulig situation
  //49:Her kommer bonussen også fra SecuredBonus og Shifterbonus
SecuredBonus:Integer=100;
ShifterBonus:Integer=100;
DestroyTrapPenalty:Integer=200;

Type
TMap=Array[0..PSqrMaxS] of Integer;
TStdListe=Array[1..PPMaxSize] of Integer;
TBlk=Record
  Antal:Integer;
  Pos:Array[1..6] of Integer;
end;

Var
Form1:TForm1;
Map:TMap;
PlMap:Array[2..4] of TMap;
TopP:TStdListe;
GameOver:Boolean=False;
IsPlaying:Boolean=False;
GameStart:Boolean;//True=Et spil er startet, men ingen brikker er endnu placeret.
StandardSize:Boolean=True;
Pause:Boolean=False;
PauseCPU:Boolean=False;
CPUMoving:Boolean=False;
FitResize:Boolean=True;
ManglerAtGentegne:Boolean=False;
ErrorTjek:Integer=0;
CellSize,CellsLeft,ErrorVar,AntalMarkerede,SidsteVinder:Integer;
SizeX:Integer=7;
SizeY:Integer=6;
HvemBegynder:Integer=4;
BlinkTilbage:Integer=0;
HvisTurMark:Integer;
HvemBegyndteSidst:Integer=4;
ProposeMove:Integer;//Trækforslag fra CPU med P.M. i sværhedsgræd
Marks:Array[1..22] of Integer;
CP:Integer=2;//Spiller1=2, spiller2=4
Farve:Array[2..4] of Integer=(3,0,4);
PlT:Array[2..4] of Integer=(Menneske,0,CPUHalvSvaer);
  //Boolean(PlT[X]) er true hvis computer
LastNow:Double=0;
SortL:TStdListe;
ValueL:Array[0..4095] of Integer;
AntalPP:Array[0..4095] of Integer;
PP:Array[0..4095,1..2] of Integer;
  //Der vil højst være 2 frie felter med vinderpotentiale pr ValueL[x]
Blk:Array[1..MaxRekLevel,1..14] of TBlk;
  //Blk=Blokeringer  Blk[CellsLeft,RækkeNr]
Games:Array[0..1376255] of byte;
Vindere:Array[0..32767] of byte;
  //PrevGames[(RykNr ShL 15) or SpilNr]=PrevGames[SpilNr,RykNr]
  //RykNr tilhører intervallet [0..41]
AntalGames:Integer;//PAntalGames=n <=> n+1 spil gemt
CurrentGame:Array[0..41] of byte;

implementation

{$R *.DFM}

Uses Unit2;

Procedure LoadGames;//Kun standardsize
Var I,J:Integer;
begin
If FileExists(''Games.txt'') then With Form1.ListBox2 do begin
Items.Clear;
Items.LoadFromFile(''Games.txt'');
AntalGames:=Pred(Items.Count);//+1
For J:=0 to AntalGames do begin
  Vindere[J]:=Ord(Items[J][1]) Xor 48;
  For I:=0 to 41 do Games[(J ShL 15) or I]:=Ord(Items[J][I+3]) Xor 48;
end;
end else AntalGames:=-1;
end;

Procedure AddGame;//Kun standardsize
Var
I:Integer;
S:String;
begin
Inc(AntalGames);
Vindere[AntalGames]:=SidsteVinder;
With Form1.ListBox2 do begin
S:=Char(SidsteVinder or 48)+''-                                          '';
For I:=0 to 41 do begin
  Games[(I ShL 15) or AntalGames]:=CurrentGame[I];
  S[I+3]:=Char(48 or CurrentGame[I]);
end;
Items.Add(S);
Items.SaveToFile(''Games.txt'');
end;
end;

Procedure CompareWithPreviouslyGames(Var Liste:TStdListe);//Kun standardsize
Var
I,J,Move,Pl:Integer;
Ens,Spejling:Boolean;
L,Antal,Sum:Array[1..7] of Integer;
  //L: Bruges til at genkende stillingen.
  //Antal: Antal gange der er spillet videre på hvert næste træk.
  //Sum: Antal point der er opnået ved at spille videre på hvert næste træk.
  //Sum/Antal er et mål for hvor godt trækket er.
begin
If CellsLeft>42 then begin
ShowMessage(''Compare kan kun benyttes til standardstørrelsen.'');
Exit;
end;
If Not Boolean(CellsLeft) then begin
ShowMessage(''Alle brikker er placeret.'');
Exit;
end;
For I:=1 to 7 do begin
Antal[I]:=0;
Sum[I]:=0;
end;
For J:=0 to AntalGames do begin
Spejling:=True;
Repeat
  For I:=1 to 7 do L[I]:=6;
  Pl:=HvemBegyndteSidst;
  Ens:=True;
  For I:=1 to 43-CellsLeft do begin
  Move:=Games[(I ShL 15) or J];
  If Spejling then Move:=8-Move;
  If Map[(Move ShL Ln2MaxSize) or L[Move]]<>Pl then begin
    Ens:=False;
    Break;
  end;
  Pl:=Pl Xor 6;
  end;
  If Ens then begin
  Move:=Games[(I ShL 15) or J];//Efter for-løkken er I=(43-CellsLeft)+1
  If Spejling then Move:=8-Move;
  Inc(Antal[Move]);
  If Vindere[J]<>IngenVinder then begin
    If (CP=HvemBegyndteSidst) Xor (Vindere[J]=BegynderenTabte) then
    //Svarer til at CP vil vinde.
    Inc(Sum[Move]) else Dec(Sum[Move]);
  end;
  end;
  Spejling:=Not Spejling;
Until Spejling;
end;
For I:=1 to 7 do If Boolean(Antal[I]) then Inc(Liste[I],(Sum[I]*10000) div Antal[I]);
end;

Function Min(A,B:Integer):Integer;
begin
If A>B then Min:=B else Min:=A;
end;

Function Max(A,B:Integer):Integer;
begin
If A>B then Max:=A else Max:=B;
end;

Function CPUvsCPU:Boolean;
begin
CPUvsCPU:=Boolean(PlT[Pl1]) and Boolean(PlT[Pl2]);
end;

Procedure Convert(Var X:Integer);
begin
X:=Succ(Pred(X) Div CellSize);
If X<1 then X:=1 else If X>SizeX then X:=SizeX;
end;

Procedure DrawM(Pos:Integer; Invert:Boolean);
Var X,Y,Margin:Integer;
begin
X:=Pos ShR Ln2MaxSize;
Y:=Pos and PMaxSize;
With Form1.Canvas do begin
Brush.Style:=bsSolid;
If Invert then Pen.Mode:=pmNot;
Margin:=CellSize ShR 2;
Ellipse(CellSize*Pred(X)+2+Margin,CellSize*Pred(Y)+2+Margin,
  CellSize*X-Margin,CellSize*Y-Margin);
Pen.Mode:=pmCopy;
end;
end;

Procedure RemoveBlink;
Var I:Integer;
begin
If Boolean(BlinkTilbage and 1) then
For I:=1 to AntalMarkerede do DrawM(Marks[I],True);
Form1.Marker.Enabled:=False;
BlinkTilBage:=0;
end;

Procedure ShowError(Error:String);
begin
Form1.Canvas.Brush.Style:=BsClear;
Form1.Canvas.TextOut(5,Form1.ClientHeight-30,Error);
end;

Procedure SaveSettings;
Var
Fil:File;
Temp:Integer;
begin
AssignFile(Fil,''4PaaStribe-DefaultSettings.DS'');
ReWrite(Fil,1);
BlockWrite(Fil,SizeX,SizeOf(SizeX));
  BlockWrite(Fil,SizeY,SizeOf(SizeY));
  StandardSize:=(SizeX=7) and (SizeY=6);
  BlockWrite(Fil,PlT,SizeOf(PlT));
  BlockWrite(Fil,ProposeMove,SizeOf(ProposeMove));
  BlockWrite(Fil,Farve,SizeOf(Farve));
  BlockWrite(Fil,HvemBegynder,SizeOf(HvemBegynder));
  //Gem form1''s placering på skærmen
  Form1.FormResize(Form1);
  Temp:=Form1.Left;
  BlockWrite(Fil,Temp,SizeOf(Temp));
  Temp:=Form1.Top;
  BlockWrite(Fil,Temp,SizeOf(Temp));
  Temp:=Form1.Width;
  BlockWrite(Fil,Temp,SizeOf(Temp));
  Temp:=Form1.Height;
  BlockWrite(Fil,Temp,SizeOf(Temp));
CloseFile(Fil);
end;

Procedure SetDefaultOptions;
Var
Fil:File;
Temp:Integer;
begin
If FileExists(DefSettingsName) then begin
AssignFile(Fil,DefSettingsName);
Reset(Fil,1);
BlockRead(Fil,SizeX,SizeOf(SizeX));
  BlockRead(Fil,SizeY,SizeOf(SizeY));
  BlockRead(Fil,PlT,SizeOf(PlT));
  BlockRead(Fil,ProposeMove,SizeOf(ProposeMove));
  BlockRead(Fil,Farve,SizeOf(Farve));
  BlockRead(Fil,HvemBegynder,SizeOf(HvemBegynder));
  //Hent form1''s placering på skærmen
  FitResize:=False;
  BlockRead(Fil,Temp,SizeOf(Temp));
  Form1.Left:=Temp;
  BlockRead(Fil,Temp,SizeOf(Temp));
  Form1.Top:=Temp;
  BlockRead(Fil,Temp,SizeOf(Temp));
  Form1.Width:=Temp;
  BlockRead(Fil,Temp,SizeOf(Temp));
  FitResize:=True;
  Form1.Height:=Temp;
CloseFile(Fil);
end;//else har SizeX,Farve,osv. default-værdier.
end;

Function AntalKolonner:Integer;
Var Antal,I:Integer;
begin
Antal:=0;
For I:=1 to SizeX do If Boolean(TopP[I]) then Inc(Antal);
AntalKolonner:=Antal;
end;

Procedure DrawCell(CellNr:Integer);
Var X,Y,Margin:Integer;
begin
X:=CellNr ShR Ln2MaxSize;
Y:=CellNr and PMaxSize;
If Map[CellNr]<>Tom then With Form1.Canvas do begin
Brush.Style:=bsSolid;
Brush.Color:=Farver[Farve[Map[CellNr]]];
Pen.Color:=Farver[Farve[Map[CellNr]]];
Margin:=CellSize ShR 4;
Ellipse(CellSize*Pred(X)+2+Margin,CellSize*Pred(Y)+2+Margin,
  CellSize*X-Margin,CellSize*Y-Margin);
end;
end;

Procedure Gentegn;
Var I,J:Integer;
begin
If CPUMoving then begin
ManglerAtGentegne:=True;
Exit;
end;
With Form1.Canvas do begin
Brush.Color:=ClBtnFace;
FillRect(Rect(0,0,Form1.ClientWidth,Form1.ClientHeight));
Brush.Color:=ClBlack;
FrameRect(Rect(0,0,Form1.ClientWidth,Form1.ClientHeight));
For I:=1 to SizeX do begin
  For J:=1 to SizeY do begin
  Brush.Color:=ClBlack;
  FrameRect(Rect(Succ(CellSize*Pred(I)),Succ(CellSize*Pred(J)),
    Succ(CellSize*I),Succ(CellSize*J)));
  DrawCell((I ShL Ln2MaxSize) or J);
  end;
end;
end;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
Timer2.Enabled:=True;
end;

Procedure PrepareField;
Var I,J:Integer;
begin
For I:=0 to Succ(SizeX) do begin
Map[I ShL Ln2MaxSize]:=Udenfor;
Map[(I ShL Ln2MaxSize) or Succ(SizeY)]:=Udenfor;
end;
For J:=0 to Succ(SizeY) do begin
Map[J]:=Udenfor;
Map[(Succ(SizeX) ShL Ln2MaxSize) or J]:=Udenfor;
end;
For I:=1 to SizeX do begin
TopP[I]:=SizeY;
For J:=1 to SizeY do Map[(I ShL Ln2MaxSize) or J]:=Tom;
end;
PlMap[2]:=Map;
PlMap[4]:=Map;
end;

Procedure NewGame;
begin
Randomize;
RemoveBlink;
PrepareField;
CellsLeft:=SizeX*SizeY;
If GameStart then CP:=HvemBegyndteSidst Xor 6 else
Case HvemBegynder of
  0  :CP:=HvemBegyndteSidst Xor 6;
  1  :CP:=Succ(Random(2)) ShL 1;
  4  :;//CP:=CP;
  5  :CP:=CP Xor 6;
  else CP:=(HvemBegynder ShL 1)-2;//Hvembegynder=2 eller 3
end;
GameOver:=False;
HvemBegyndteSidst:=CP;
IsPlaying:=False;
GameStart:=True;
Gentegn;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
LoadGames;
SetDefaultOptions;
GetValueList;
PrepareField;
If (Screen.Height-50<Top) or (Screen.Width-50<Left) then begin
//Formen skal ikke placeres udenfor skærmen, hvis der køres i en lav opløsning
Top:=(Screen.Height-Height) ShR 1;
Left:=(Screen.Width-Width) ShR 1;
end;
Randomize;
NewGame;
end;

procedure TForm1.FormResize(Sender: TObject);
Var Y:Integer;
begin
Timer2.Enabled:=True;
If FitResize then begin
CellSize:=(ClientWidth-2) Div SizeX;
Y:=(ClientHeight-2) Div SizeY;
If Y<CellSize then CellSize:=Y;
ClientWidth:=SizeX*CellSize+2;
ClientHeight:=SizeY*CellSize+2;
end;
end;

Function ExitGame:Boolean;
begin
NewGame;
Gentegn;
ExitGame:=False;
end;

Procedure AddMark(Pos:Integer);
begin
Inc(AntalMarkerede);
Marks[AntalMarkerede]:=Pos;
end;

Procedure SetOneBlink(Pos:Integer);
begin
RemoveBlink;
Form1.Marker.Enabled:=True;
BlinkTilBage:=DefaultBlink;
AntalMarkerede:=0;
AddMark(Pos);
end;

Function New4S(Pos:Integer; VisMarkerede:Boolean):Boolean;
Var Antal,F,T,P:Integer;//Fra,Til,Player
begin
P:=Map[Pos];
If VisMarkerede then SetOneBlink(Pos);
New4S:=False;
//Tjek lodret...
Antal:=1;
F:=Pred(Pos);
While Map[F]=P do begin
Inc(Antal);
Dec(F);
end;
T:=Succ(Pos);
While Map[T]=P do begin
Inc(Antal);
Inc(T);
end;
If Antal>3 then begin
New4S:=True;
If VisMarkerede then begin
  Inc(F);
  Repeat
  If F<>Pos then AddMark(F);
  Inc(F);
  Until F=T;
end;
end;
//Tjek Vandret...
Antal:=1;
F:=Pos-MaxSize;
While Map[F]=P do begin
Inc(Antal);
Dec(F,MaxSize);
end;
T:=Pos+MaxSize;
While Map[T]=P do begin
Inc(Antal);
Inc(T,MaxSize);
end;
If Antal>3 then begin
New4S:=True;
If VisMarkerede then begin
  Inc(F,MaxSize);
  Repeat
  If F<>Pos then AddMark(F);
  Inc(F,MaxSize);
  Until F=T;
end;
end;
//Tjek skrå \-retning...
Antal:=1;
F:=Pos-SMaxSize;
While Map[F]=P do begin
Inc(Antal);
Dec(F,SMaxSize);
end;
T:=Pos+SMaxSize;
While Map[T]=P do begin
Inc(Antal);
Inc(T,SMaxSize);   
end;
If Antal>3 then begin
New4S:=True;
If VisMarkerede then begin
  Inc(F,SMaxSize);
  Repeat
  If F<>Pos then AddMark(F);
  Inc(F,SMaxSize);
  Until F=T;
end;
end;
//Tjek skrå /-retning...
Antal:=1;
F:=Pos-PMaxSize;
While Map[F]=P do begin
Inc(Antal);
Dec(F,PMaxSize);
end;
T:=Pos+PMaxSize;
While Map[T]=P do begin
Inc(Antal);
Inc(T,PMaxSize);
end;
If Antal>3 then begin
New4S:=True;
If VisMarkerede then begin
  Inc(F,PMaxSize);
  Repeat
  If F<>Pos then AddMark(F);
  Inc(F,PMaxSize);
  Until F=T;
end;
end;
end;

Procedure PlacePiece(X:Integer);
Var
Pos,Y:Integer;
begin
If StandardSize then CurrentGame[43-CellsLeft]:=X;
GameStart:=False;
PauseCPU:=True;//Undgå at computeren spiller videre under showmessages;
Y:=TopP[X];
Pos:=(X ShL Ln2MaxSize) or Y;
If Y<1 then showError(''Error. CPU forsøger at placere på fyldt kolonne.'');
Dec(TopP[X]);
Map[Pos]:=CP;
DrawCell(Pos);
Dec(CellsLeft);
HvisTurMark:=0;
If New4S(Pos,True) then begin
GameOver:=True;
If CP=HvemBegyndteSidst then SidsteVinder:=BegynderenVandt
else SidsteVinder:=BegynderenTabte;
end;
If Not(GameOver or Boolean(CellsLeft)) then begin
GameOver:=True;
SidsteVinder:=IngenVinder;
CPUMoving:=False;//Så der atter kan gentegnes, hvis showmessages flyttes
ShowMessage(''Spillet Endte uafgjort!'');
end;
IsPlaying:=Not GameOver;
CP:=CP Xor 6;
PauseCPU:=False;
end;

Function WeakCPUThink:Integer;
Var I,Pos:Integer;
begin
//Kan der placeres 4 på stribe. Bloker kun muligvis (50%)
For I:=1 to SizeX do if Boolean(TopP[I]) then begin
Pos:=(I ShL Ln2MaxSize) or TopP[I];
Map[Pos]:=CP;
If Boolean(Random(2)) and New4S(Pos,False) then begin
  WeakCPUThink:=I;
  Exit;
end;
Map[Pos]:=Tom;
end;
//Kan modstanderen forhindres i at sætte 4 på stribe. Bloker kun muligvis (50%)
For I:=1 to SizeX do if Boolean(TopP[I]) then begin
Pos:=(I ShL Ln2MaxSize) or TopP[I];
Map[Pos]:=CP Xor 6;
If Boolean(Random(2)) and New4S(Pos,False) then begin
  WeakCPUThink:=I;
  Exit;
end;
Map[Pos]:=Tom;
end;
//Placer brikken tilfældigt
I:=Succ(Random(SizeX));
Repeat
I:=Succ(I mod SizeX);
Until Boolean(TopP[I]);
WeakCPUThink:=I;
end;

Function CPUThink:Integer;
Var
I,J,Pos:Integer;
Avoid:Array[1..PPMaxSize] of Boolean;
begin
//Kan der placeres 4 på stribe?
For I:=1 to SizeX do if Boolean(TopP[I]) then begin
Pos:=(I ShL Ln2MaxSize) or TopP[I];
Map[Pos]:=CP;
If New4S(Pos,False) then begin
  CPUThink:=I;
  Exit;
end;
Map[Pos]:=Tom;
end;
//Kan modstanderen forhindres i at sætte 4 på stribe?
For I:=1 to SizeX do if Boolean(TopP[I]) then begin
Pos:=(I ShL Ln2MaxSize) or TopP[I];
Map[Pos]:=CP Xor 6;
If New4S(Pos,False) then begin
  CPUThink:=I;
  Exit;
end;
Map[Pos]:=Tom;
end;
//Prøv at placere brikker så modst. ikke får 4 på stribe ved at placere ovenover...
For I:=1 to SizeX do if TopP[I]>1 then begin//Skal være plads til 2 brikker
Pos:=(I ShL Ln2MaxSize) or TopP[I];
Map[Pos]:=CP;
Map[Pred(Pos)]:=CP Xor 6;
Avoid[I]:=New4S(Pred(Pos),False);
Map[Pred(Pos)]:=Tom;
Map[Pos]:=Tom;
end else Avoid[I]:=Not Boolean(TopP[I]);
For I:=1 to SizeX do If not Avoid[I] then begin
Repeat
  J:=Succ(Random(SizeX));//Vælg tilfældigt felt
Until not Avoid[J];
CPUThink:=J;
Exit;
end;
//Placer brikken tilfældigt - modstanderen vil vinde
I:=Random(SizeX);
Repeat
I:=Succ(I mod SizeX);
Until Boolean(TopP[I]);
CPUThink:=I;
end;

Procedure TjekError(Pos:Integer);
Var I:Integer;
begin
DrawM(Pos,True);
{Inc(ErrorTjek);
Form1.Caption:=IntToStr(ErrorTjek);}
{Pause:=True;
Repeat
Application.ProcessMessages;
Until Not Pause;}
For I:=0 to 4000000 do;
DrawM(Pos,True);
end;

Procedure CreateValueList;//Virker
Type
TMyType=Record
  AntalZ,Value:Integer;
  BrugtTomme:Array[1..3] of Integer;
end;
Var
A,B,I,J,F,T,Y,Z,BonusFelter,Current,AntalX,AntalDirect:Integer;
WhereIsP4S:Array[1..7] of Integer;//Where Is Possible 4 Straight. Fri/FriTom
AntalY:Array[1..6] of Integer;
Fil:File;
Bonus:Boolean;
L:Array[0..8] of Integer;
Fyldte:Array[1..7] of Boolean;
Komb:Array[1..6,1..3] of TMyType;
S:String;
Function MakeS:String;
  Const Chars:Array[0..3] of Char=(''#'',''_'',''x'','' '');
  Var
  I:Integer;
  S:String;
  begin
  SetLength(S,7);
  For I:=1 to 7 do S[I]:=Chars[L[I]];
  S[4]:=''X'';
  MakeS:=S;
  end;
Function PossiblePos(J:Integer):String;
  begin
  Case AntalPP[J] of
  0:PossiblePos:='''';
  1:PossiblePos:=''  P1=''+IntToStr(PP[J,1]);
  2:PossiblePos:=''  P1=''+IntToStr(PP[J,1])+''  P2=''+IntToStr(PP[J,2]);
  end;
  end;
Function Call(XNr:Integer):Integer;//Returnerer MaxSum
  Var I,Max,Temp:Integer;
  Function PladsTil(Var New:TMyType):Boolean;
    Var I:Integer;
    begin
    PladsTil:=True;
    For I:=1 to New.AntalZ do If Fyldte[New.BrugtTomme[I]] then begin
    PladsTil:=False;
    Break;
    end;
    end;
  Procedure Invert(Var Inv:TMyType);
    Var I:Integer;
    begin
    For I:=1 to Inv.AntalZ do
    Fyldte[Inv.BrugtTomme[I]]:=Not Fyldte[Inv.BrugtTomme[I]];
    end;
  begin
  If Boolean(XNr) then begin//Ellers returneres 0
  Max:=Call(Pred(XNr));//=Mulighed 1: Der tilføres ikke nogen fra denne x-værdi
  For I:=1 to AntalY[XNr] do If PladsTil(Komb[XNr,I]) then begin
    Invert(Komb[XNr,I]);
    Temp:=Call(Pred(XNr))+Komb[XNr,I].Value;
    If Temp>Max then Max:=Temp;
    Invert(Komb[XNr,I]);
  end;
  Call:=Max;
  end else Call:=0;
  end;
begin
Form1.ListBox1.Clear;
L[0]:=Udenfor;
L[4]:=SelfPl;
L[8]:=Udenfor;
For I:=1 to 7 do Fyldte[I]:=False;
For J:=0 to 4095 do begin
L[1]:=J and 3;
L[2]:=(J ShR 2) and 3;
L[3]:=(J ShR 4) and 3;
L[5]:=(J ShR 6) and 3;
L[6]:=(J ShR 8) and 3;
L[7]:=J ShR 10;
For I:=1 to 7 do WhereIsP4S[I]:=0;
F:=3;
While Boolean(L[F] and TomOrCP) do Dec(F);
Inc(F);
T:=5;
While Boolean(L[T] and TomOrCP) do Inc(T);
Dec(T);
If T-F>2 then begin//Plads til 4 på stribe
  A:=3;
  While L[A]=SelfPl do Dec(A);
  B:=5;
  While L[B]=SelfPl do Inc(B);
  If B-A>4 then ValueL[J]:=Straight[B-A] else begin
  AntalX:=0;
  For I:=F to T do If Boolean(L[I] and Tom) then begin
    Inc(AntalX);
    Y:=0;
    For A:=Max(I-3,F) to Min(I+3,T)-3 do begin
    //Kører de intervaller [A..A+3] igennem, som det tomme felt L[I] er en del af.
    Inc(Y);
    Bonus:=True;//indtil modsat er bevist
    BonusFelter:=0;//Antal felter der hænger
      //Hvis der findes 4 på stribe vil Bonus=True men BonusL=0, hvorfor bonussen
      //bliver 0, og ikke laver ravage.
    Current:=4;//Antal aktuelt manglende brikker+1
    Z:=0;
    For B:=A to A+3 do begin
      If Boolean(L[B] and Tom) then begin
      Inc(Z);
      Komb[AntalX,Y].BrugtTomme[Z]:=B;
      If Bonus then If L[B]=1 then Bonus:=False//Et felt der ikke "hænger"
          else Inc(BonusFelter);
      end else Dec(Current);
    end;//For B
    Komb[AntalX,Y].AntalZ:=Z;
    If Not Bonus then BonusFelter:=0;
    Komb[AntalX,Y].Value:=Values[Current,BonusFelter];
    If Current=1 then//Kun én brik mangler
      For B:=A to A+3 do If Boolean(L[B] and Tom) then //Find denne
      WhereIsP4S[B]:=L[B];
    end;//For A
    AntalY[AntalX]:=Y;
  end;//For I
  //Nu skal den bedste kombination findes. Undersøg først om der eksempelvist
  //er lavet en fælde.
  AntalDirect:=0;
  AntalPP[J]:=0;
  For I:=1 to 7 do If Boolean(WhereIsP4S[I]) then
    If WhereIsP4S[I]=FriTom then begin
    Inc(AntalPP[J]);
    PP[J,AntalPP[J]]:=I-4;
    end else Inc(AntalDirect);
  If AntalDirect>1 then ValueL[J]:=5000 else ValueL[J]:=Call(AntalX);
  end;//Ikke 4 på stribe
end;//Plads til 4 på stribe
Form1.ListBox1.Items.Add(MakeS+'' &#124;&#124; Nr=''+IntToStr(J)+''  Værdi=''
  +IntToStr(ValueL[J])+PossiblePos(J));
end;//For J
Form1.ListBox1.Items.SaveToFile(''Konstanter.txt'');
Form1.ListBox1.Clear;
While InputQuery(''d'',''d'',S) do begin
For I:=0 to Pred(Form1.ListBox1.Items.Count) do
  If Copy(Form1.ListBox1.Items[I],1,7)=S then begin
    ShowMessage(Form1.ListBox1.Items[I]);
    Break;
  end;
end;
//Gem i fil til brug for programmet
If Not FileExists(''Konstanter.cpu'') then
Form1.ListBox1.Items.SaveToFile(''Konstanter.cpu'');//Sørg for at filen eksisterer
AssignFile(Fil,''Konstanter.cpu'');
Rewrite(Fil,1);
BlockWrite(Fil,ValueL,SizeOf(ValueL));
BlockWrite(Fil,AntalPP,SizeOf(AntalPP));
BlockWrite(Fil,PP,SizeOf(PP));
CloseFile(Fil);
end;

Procedure GetValueList;//Virker
Var Fil:File;
begin
If FileExists(''Konstanter.cpu'') then begin
AssignFile(Fil,''Konstanter.cpu'');
Reset(Fil,1);
BlockRead(Fil,ValueL,SizeOf(ValueL));
BlockRead(Fil,AntalPP,SizeOf(AntalPP));
BlockRead(Fil,PP,SizeOf(PP));
CloseFile(Fil);
end else CreateValueList;
end;

Function TjekValue(PTurn,X,RekLevel:Integer):Integer;
// Returnerer en af følgende muligheder
// >$200000: Kan få 4 på stribe
// >$040000: Skal forhindre 4 på stribe
// >$008000: Kan lave fælde
// >$001000: Skal forhindre modstanderen i at lave fælde
// ellers  : Kun feltets værdi.
// Hvis x>$000800 da vil (x and $7FF) være selve feltets værdi.
Var
F,T,Y,MinF,MaxT,Potens2,Pos,Index,Sum,Temp,TrapY,Straf:Integer;
SelfMoving:Boolean;
Function Tjek(CPlTjek:Integer; Var Map:TMap):Integer;
begin
Sum:=0;
SelfMoving:=PTurn=CPlTjek;

//$2 Tjek Vandret...
Index:=0;
Potens2:=4;
F:=Pos-MaxSize;
MinF:=Pos-MaxSize4;
While Boolean(Map[F] and TomOrCP) and (F<>MinF) do begin
//Boolean(Map[X,J] and TomOrCP) er sand hvis feltet enten er tomt eller
//indeholder CP. Hvis Fra/Til>3 så er de resterende mulige felter
//uden betydning, da disse ikke kan danne 4 på stribe med det aktuelle felt.
If Map[Succ(F)]=Tom then//Ovenstående felt frit
    Inc(Index,FriTom ShL Potens2)
else Inc(Index,Map[F] ShL Potens2);
Dec(F,MaxSize);
Dec(Potens2,2);
end;
T:=Pos+MaxSize;
MaxT:=Pos+MaxSize4;
Potens2:=6;
While Boolean(Map[T] and TomOrCP) and (T<>MaxT) do begin
If Map[Succ(T)]=Tom then//Ovenstående felt frit
    Inc(Index,FriTom ShL Potens2)
else Inc(Index,Map[T] ShL Potens2);
Inc(T,MaxSize);
Inc(Potens2,2);
end;
Inc(Sum,ValueL[Index]);
While Boolean(AntalPP[Index]) do begin//Trap
//Her er PP[AntalPP[Index]] uden betydning, da der undersøges vandret
//Secured:=Boolean((CellsLeft Xor Y) and 1) Xor SelfMoving;//Xor i stedet for -
//Skifter:=Boolean(Y and 1);
//TrapPos:=Pos+(PP[Index,AntalPP[Index]] ShL Ln2MaxSize);
If Boolean((CellsLeft Xor Y) and 1) Xor SelfMoving then Inc(Sum,SecuredBonus);
If Boolean(Y and 1) then Inc(Sum,ShifterBonus);
If Boolean(RekLevel) then Begin
  //Reklevel=0 i langt størstedelen af de gange, tjekvalue kaldes.
  Inc(Blk[RekLevel,Y].Antal);
  Blk[RekLevel,Y].Pos[Blk[RekLevel,Y].Antal]:=
    Pos+(PP[Index,AntalPP[Index]] ShL Ln2MaxSize);//Gem pos
end;
Dec(AntalPP[Index]);
end;

//Tjek lodret...(ingen fritsvævende)
Index:=0;
F:=Pred(Pos);
MinF:=Pos-4;
Potens2:=4;
While Boolean(Map[F] and TomOrCP) and (F<>MinF) do begin
Inc(Index,Map[F] ShL Potens2);
Dec(F);
Dec(Potens2,2);
end;
T:=Succ(Pos);
MaxT:=Pos+4;
Potens2:=6;
While Boolean(Map[T] and TomOrCP) and (T<>MaxT) do begin
Inc(Index,Map[T] ShL Potens2);
Inc(T);
Inc(Potens2,2);
end;
Inc(Sum,ValueL[Index]);

//Tjek skrå \-retning...
Index:=0;
F:=Pos-SMaxSize;
MinF:=Pos-SMaxSize4;
Potens2:=4;
While Boolean(Map[F] and TomOrCP) and (F<>MinF) do begin
If Map[Succ(F)]=Tom then//Ovenstående felt frit
    Inc(Index,FriTom ShL Potens2)
else Inc(Index,Map[F] ShL Potens2);
Dec(F,SMaxSize);
Dec(Potens2,2);
end;
T:=Pos+SMaxSize;
MaxT:=Pos+SMaxSize4;
Potens2:=6;
While Boolean(Map[T] and TomOrCP) and (T<>MaxT) do begin
If Map[Succ(T)]=Tom then//Ovenstående felt frit
    Inc(Index,FriTom ShL Potens2)
else Inc(Index,Map[T] ShL Potens2);
Inc(T,SMaxSize);
Inc(Potens2,2);
end;
Inc(Sum,ValueL[Index]);
While Boolean(AntalPP[Index]) do begin//Trap
Temp:=PP[Index,AntalPP[Index]];
TrapY:=Y Xor Temp;//Xor i stedet for +, da kun sidste ciffer skal bruges
If Boolean((CellsLeft Xor TrapY) and 1) Xor SelfMoving then Inc(Sum,SecuredBonus);
If Boolean(TrapY and 1) then Inc(Sum,ShifterBonus);
If Boolean(RekLevel) then begin
  Inc(Blk[RekLevel,Y].Antal);
  Blk[RekLevel,Y].Pos[Blk[RekLevel,Y].Antal]:=
    Pos+((Temp ShL Ln2MaxSize) or Temp);//Gem pos
end;
Dec(AntalPP[Index]);
end;

//Tjek skrå /-retning...
Index:=0;
F:=Pos-PMaxSize;
MinF:=Pos-PMaxSize4;
Potens2:=4;
While Boolean(Map[F] and TomOrCP) and (F<>MinF) do begin
If Map[Succ(F)]=Tom then//Ovenstående felt frit
    Inc(Index,FriTom ShL Potens2)
else Inc(Index,Map[F] ShL Potens2);
Dec(F,PMaxSize);
Dec(Potens2,2);
end;
T:=Pos+PMaxSize;
MaxT:=Pos+PMaxSize4;
Potens2:=6;
While Boolean(Map[T] and TomOrCP) and (T<>MaxT) do begin
If Map[Succ(T)]=Tom then//Ovenstående felt frit
    Inc(Index,FriTom ShL Potens2)
else Inc(Index,Map[T] ShL Potens2);
Inc(T,PMaxSize);
Inc(Potens2,2);
end;
Inc(Sum,ValueL[Index]);
While Boolean(AntalPP[Index]) do begin//Trap
Temp:=PP[Index,AntalPP[Index]];
TrapY:=Y Xor Temp;
If Boolean((CellsLeft Xor TrapY) and 1) Xor SelfMoving then Inc(Sum,SecuredBonus);
If Boolean(TrapY and 1) then Inc(Sum,ShifterBonus);
If Boolean(RekLevel) then begin
  Inc(Blk[RekLevel,Y].Antal);
  Blk[RekLevel,Y].Pos[Blk[RekLevel,Y].Antal]:=Pos+(Temp ShL Ln2MaxSize)-Temp;
end;
Dec(AntalPP[Index]);
end;
//Tjek retninger færdig
//Modstanderens 4 på striber/fælder skal tælle mindre end ens egne...
If SelfMoving then Tjek:=Sum else Tjek:=(Sum and $7FF) or ((Sum and $FFF800) ShR 3);
end;
begin//Selve proceduren
Y:=TopP[X];
Pos:=(X ShL Ln2MaxSize) or Y;
Straf:=0;
If Not Boolean(PlMap[PTurn,Pos]) then Straf:=DestroyTrapPenalty;
//Ens egen fælde vil blive ødelagt
If Not Boolean(PlMap[PTurn Xor 6,Pos]) then Inc(Straf,Prevent4S);
//Modstanderen kan vinde i næste ryk. Der kan godt modtages begge straffe.
Blk[RekLevel,Y].Antal:=0;
//ShowMessage(IntToStr(Tjek(PTurn Xor 6,PlMap[PTurn Xor 6])));
TjekValue:=Tjek(PTurn,PlMap[PTurn])+Tjek(PTurn Xor 6,PlMap[PTurn Xor 6])-Straf;
end;

Procedure PlaceTrap(Pl,Pos:Integer);
Var MinY,NPl:Integer;
begin
//Placer nedefra og op
MinY:=Pos and KunX;//MinY skal der ikke placeres på
NPl:=Pl Xor 6;
Repeat
PlMap[Pl,Pos]:=Udenfor;
Dec(Pos);
If Pos=MinY then Break;
PlMap[NPl,Pos]:=Udenfor;
Dec(Pos);
Until Pos=MinY;
end;

Procedure RemoveTrap(Pl,Pos:Integer);
Var MinY,NPl:Integer;
begin
//Fjern nedefra og op
MinY:=Pos and KunX;//MinY skal ikke medtages
NPl:=Pl Xor 6;
Repeat
PlMap[Pl,Pos]:=Udenfor;
Dec(Pos);
If (Pos=MinY) or Not Boolean(PlMap[NPl,Pos]) then Break;
PlMap[NPl,Pos]:=Udenfor;
Dec(Pos);
Until (Pos=MinY) or Not Boolean(PlMap[Pl,Pos]);
end;

Function TjekLevel(Turn,RekLevel,PX:Integer):Integer;//Tilhører NextGenCPU2
//Functionen placerer og fjerner selv brikken (Placeret ved x=PX) samt traps.
Var
I,Max,MaxPos,NTurn,PPos:Integer;
L:TStdListe;
Procedure PlaceTraps(Var Blk:TBlk);
  Var I:Integer;
  begin
  For I:=1 to Blk.Antal do PlaceTrap(NTurn,Blk.Pos[I]);
  //NTurn: De fælde, der placeres, er lavet af modstanderen i forrige træk.
  end;
Procedure RemoveTraps(Var Blk:TBlk);
  Var I:Integer;
  begin
  For I:=1 to Blk.Antal do RemoveTrap(NTurn,Blk.Pos[I]);
  end;
Procedure UndoOpdate;
  begin
  RemoveTraps(Blk[Succ(RekLevel),PX]);
  //Pred(RekLevel): Fælderne er lavet trækket før, da RekLevel var en større.
  Inc(TopP[PX]);
  PlMap[Turn,PPos]:=Tom;
  PlMap[NTurn,PPos]:=Tom;
  end;
begin
NTurn:=Turn Xor 6;
PPos:=(PX ShL Ln2MaxSize) or TopP[PX];
//Opdater PlMap...
PlMap[Turn,PPos]:=Turn;
PlMap[NTurn,PPos]:=NTurn;
Dec(TopP[PX]);
PlaceTraps(Blk[Succ(RekLevel),PX]);
//Opdatering slut.
MaxPos:=0;//Undgå warning
Max:=-999999999;
For I:=1 to SizeX do if Boolean(TopP[I]) then begin
L[I]:=TjekValue(Turn,I,RekLevel);
If L[I]>Max then begin
  Max:=L[I];
  MaxPos:=I;
end;
end else L[I]:=-999999999;
If Max>LSave4S then begin
TjekLevel:=Save4S;
UndoOpdate;
Exit;
end;
If Max>LPrevent4S then begin
For I:=1 to SizeX do if L[I]>LPrevent4S then If I<>MaxPos then begin
  //En fælde. modstanderen har vundet
  TjekLevel:=-Save4S;
  UndoOpdate;
  Exit;
end;
end else If Max>LSaveTrap then begin
//Sikker sejr. Der kan laves en fælde, og modstanderen har ingen modtræk.
TjekLevel:=Save4S;
UndoOpdate;
Exit;
end;
If Boolean(RekLevel) then begin//Not final RekLevel
If Max>LPrevent4S then begin
  //Computeren har kun én mulighed for at placere sin brik, idet den skal
  //forhindre modstanderen i at få 4 på stribe.
  Max:=Max and MaxOrdValue;//Computeren skal ikke favourisere en situation,
    //hvor den kan forhindre modstanderen i at få 4 på stribe.
    //Max er ikke-negativ.
  If Max<0 then showmessage(''Error: Max<0'');
  Dec(Max,TjekLevel(NTurn,Pred(RekLevel),MaxPos));//Dec fordi modst. pot. fraregnes
end else begin//Placer mest værdifulde sted. Der er kun tale om ordinære værdier.
  Max:=-MaxOrdValue;
  For I:=1 to SizeX do if Boolean(TopP[I]) then begin
  L[I]:=L[I] and MaxOrdValue;//PreventTrap skal sies fra.
  Dec(L[I],TjekLevel(NTurn,Pred(RekLevel),I));//Dec fordi modst. pot. fraregnes
  If L[I]>Max then Max:=L[I];
  end;
end;
end;
UndoOpdate;
TjekLevel:=Max;
end;

Procedure CreateMaps;
Var I,J,Player,Pos:Integer;
begin
For J:=1 to SizeY do For I:=1 to SizeX do begin//Ajourfør PlMap
Pos:=(I ShL Ln2MaxSize) or J;
PlMap[Pl1,Pos]:=Map[Pos];
If Map[Pos]<Pl1 then PlMap[Pl2,Pos]:=Map[Pos] else PlMap[Pl2,Pos]:=Map[Pos] Xor 6;
end;
Player:=Pl1;
Repeat
For I:=1 to SizeX do For J:=1 to Pred(TopP[I]) do begin
  //Pred:En fælde kan ikke befinde sig umiddelbart over et ikke-tomt felt.
  Pos:=(I ShL Ln2MaxSize) or J;
  Map[Pos]:=Player;
  If New4S(Pos,False) then PlaceTrap(Player,Pos);
  Map[Pos]:=Tom;
end;
Inc(Player,2);
Until Player>Pl2;
end;

Function NextGenCPU2:Integer;
Const RekLevels:Array[3..6,2..PPMaxSize] of Integer=
    //der udregnes 2 halvtræk længere frem, end der står i listen.
    //Hvis der kun er én kolonne fri, placeres der straks
    ((0,0,0,0,0,0,0,0,0,0,0,0,0),
//    ((1,1,1,1,1,1,1,1,1,1,1,1,1),//Max 2744 træk
    (10,6,4,3,3,2,2,2,2,1,1,1,1),//Max 10000 træk
    (10,8,6,5,4,4,3,3,3,2,2,2,2),//Max 120000 træk
    (10,10,8,6,5,5,4,4,4,3,3,3,3));//Max 1100000 træk
Var
I,Max,MaxPos,RekLevel:Integer;
L:TStdListe;
begin
NextGenCPU2:=0;//Undgå warning
MaxPos:=0;//Undgå warning
If AntalKolonner=1 then begin//Kun en mulighed - placer straks
For I:=1 to SizeX do if Boolean(TopP[I]) then NextGenCPU2:=I;
Exit;
end;
CreateMaps;
RekLevel:=Min(CellsLeft-2,RekLevels[PlT[CP],AntalKolonner]);
  //CellsLeft-2 fordi den første brik placeres af denne procedure, og fordi
  //TjekLevel først stopper ved RekLevel=0
Max:=-999999999;//Mindre end nogen værdi TjekLevel vil returnere
For I:=1 to SizeX do if Boolean(TopP[I]) then begin
L[I]:=TjekValue(CP,I,RekLevel);
If L[I]>Max then begin
  Max:=L[I];
  MaxPos:=I;
end;
end else L[I]:=-999999999;
If Max>LSaveTrap then begin//Udfør nødtvunget træk
NextGenCPU2:=MaxPos;
Exit;
end;
For I:=1 to SizeX do if L[I]>0 then L[I]:=L[I] and MaxOrdValue;
//PreventTrap skal fratrækkes.
Max:=-999999999;
For I:=1 to SizeX do if Boolean(TopP[I]) then begin
Application.ProcessMessages;//Tillad blink ved CPU vs CPU
L[I]:=(L[I]-TjekLevel(CP Xor 6,RekLevel,I))*(56+Random(17));
  //Dec fordi modst. potentiale skal fraregnes
If L[I]>Max then begin
  Max:=L[I];
  MaxPos:=I;
end;
end;
//Showmessage(inttostr(max));
NextGenCPU2:=MaxPos;
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
If Pause then begin
Pause:=False;
Exit;
end;
If CPUMoving then Exit;
If GameOver then begin
GameOver:=False;
If Button=mbRight then AddGame;
NewGame;
Exit;
end;
If Button=mbLeft then begin
If Not Boolean(PlT[CP]) then begin
  Convert(X);
  If Boolean(TopP[X]) then PlacePiece(X);
end;
end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
If Boolean(PlT[CP]) and Not(PauseCPU or GameOver or CPUMoving) then begin
If CPUvsCPU then If Now<LastNow+0.00002 then Exit;
LastNow:=Now;
CPUMoving:=True;
Case PlT[CP] of
  1:PlacePiece(WeakCPUThink);
  2:PlacePiece(CPUThink);
  else PlacePiece(NextGenCPU2);
end;
CPUMoving:=False;
If ManglerAtGentegne then begin
  Gentegn;
  ManglerAtGentegne:=False;
end;
end;
end;

procedure TForm1.Timer2Timer(Sender: TObject);
begin
Gentegn;
Timer2.Enabled:=False;
end;

procedure TForm1.Options1Click(Sender: TObject);
begin
If CPUMoving then Exit;
GameStart:=False;
PauseCPU:=True;
Application.CreateForm(TForm2, Form2);
Enabled:=False;
Form2.Show;
end;

procedure TForm1.Nytspil1Click(Sender: TObject);
begin
If CPUMoving then Exit;
NewGame;
end;

procedure TForm1.Quit1Click(Sender: TObject);
begin
If CPUMoving then Exit;
Close;
end;

procedure TForm1.About1Click(Sender: TObject);
begin
If CPUMoving then Exit;
Timer2.Enabled:=False;
ShowMessage(''4 på stribe version 1.5 (10 juni 1999).  Lavet af Jesper Torp Kristensen ''+
''(JesperTK@Hotmail.com)  v.h.a. Borland Delphi 3.  Spillet gælder om at få ''+
''4 af ens egne brikker til at ligge på stribe (skrå tæller også). ''+
''Hvis der trykkes nyt spil, uden at et er i gang, starter den anden spiller. ''+
''Resten af teksten er en beskrivelse af de hidtidige versioner. ''+
''Version 1.0 - omkr. 20 maj 99: Programmet omfatter kun selve spillepladen med valgfri størrelse. ''+
''Det eneste computeren tjekker er, om den kan få eller forhindre 4 på stribe. ''+
''Version 1.1 - omkr. 23 maj 99: Computeren placerer ikke længere en brik, så modstanderen kan få ''+
''4 på stribe ved at placere ovenover. Der eksperimenteres med nye algoritmer ''+
''til at forbedre computerens intelligens, mens de spiller elendigt. ''+
''Computeren kan nu tildele de enkelte trækmuligheder point ud fra deres potentiale. ''+
''Version 1.2 - 27 maj: Ny computer-intelligens. Computeren kan ''+
''nu tænke 3 træk frem, og er i stand til at slå selv garvede spillere. ''+
''Version 1.3 - omkr. 31 maj: Bruger-menuer tilføjes, valgfri spilstørrelse, ''+
''Sværhedsgrader fra latterlig nem til halvsvær. ''+
''Version 1.4 - 5 juni: Større brugervenlighed (foreslå træk, gem settings, osv.). Ny ''+
''Sværhedsgrad:Langsom. Væsentlig hastighedsoptimering (32% hurtigere). ''+
''Version 1.5 - 10 juni: Endnu en hastighedsoptimering (40% hurtigere). ''+
''Compuren er samtidig blevet klogere, idet den tager højde for flere ''+
''stillingsmæssige detajler.'');
Timer2.Enabled:=True;
end;

procedure TForm1.MarkerTimer(Sender: TObject);
Var I:Integer;
begin
Dec(BlinkTilbage);
For I:=1 to AntalMarkerede do DrawM(Marks[I],True);
If Not Boolean(BlinkTilbage) then Marker.Enabled:=False;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
If CPUMoving or Boolean(PlT[CP]) or GameOver then Exit;
Convert(X);
If X<>(HvisTurMark ShR Ln2MaxSize) then begin
If Boolean(HvisTurMark and PMaxSize) then begin
  Canvas.Brush.Color:=ClBtnFace;
  Canvas.Pen.Color:=ClBtnFace;
  DrawM(HvisTurMark,False);
end;
HvisTurMark:=(X ShL Ln2MaxSize) or TopP[X];
If Boolean(HvisTurMark and PMaxSize) then begin
  Canvas.Brush.Color:=Farver[Farve[CP]];
  Canvas.Pen.Color:=Canvas.Brush.Color;
  DrawM(HvisTurMark,False);
end;
end;
end;

procedure TForm1.Afbryd1Click(Sender: TObject);
begin
GameOver:=True;
IsPlaying:=False;
end;

procedure TForm1.Trkforslag1Click(Sender: TObject);
Var Move:Integer;
begin
If Boolean(PlT[CP]) then Exit;
CPUMoving:=True;
Trkforslag1.Caption:=''Tænker...'';
PlT[CP]:=ProposeMove;
Case ProposeMove of
1:Move:=WeakCPUThink;
2:Move:=CPUThink;
else Move:=NextGenCPU2;
end;
PlT[CP]:=Menneske;
DrawM((Move ShL Ln2MaxSize) or TopP[Move],True);
Trkforslag1.Caption:=''Trækforslag'';
CPUMoving:=False;
end;

end.
Avatar billede jespertk Nybegynder
15. juni 1999 - 11:16 #1
Jeg er desperat
Avatar billede pbr Nybegynder
15. juni 1999 - 13:52 #2
Hvad siger programmet når du kører det?
Avatar billede cyberesben Nybegynder
15. juni 1999 - 23:17 #3
oooorv hvaaaaaaaaad man! det er sgu en bunke kode der vil noget!
Avatar billede snowball Novice
16. juni 1999 - 14:41 #4
Spild af go' serverplads efter min mening.

Snowball
Avatar billede blackman Nybegynder
25. juni 1999 - 15:21 #5
Hvis der er nogle der finder de fem fejl ud fra ovenstående beskrivelse, så har vi et job til vedkommende :-))

Lars
Avatar billede cyberesben Nybegynder
25. juni 1999 - 21:09 #6
ærgerligt at man ikke kan delphi, hva'?
Avatar billede blat Nybegynder
28. juni 1999 - 03:00 #7
Lidt svært at debugge uden hele
koden (forms etc)
Avatar billede cybermike Nybegynder
29. juni 1999 - 02:18 #8
Prøv at sende mig hele kode i en zip fil, så skal jeg se på det!

uf13@hotmail.com

mvh Mikkel
Avatar billede TRoXa Novice
19. august 1999 - 15:57 #9
jeg kan også godt prøve at se på det hvis du giver mig koden... Det er lidt uoverskueligt at se på den kode du har indsat :)

troxa_2000@hotmail.com

mvh TRoXa
Avatar billede lrj Nybegynder
25. oktober 1999 - 22:25 #10
Æh, hvordan står det til på job-markedet. Er problemerne blevet løst eller hvad?

Ovenstående opgave kan faktisk ikke rigtig løses uden et dump af formen - meget gerne som tekst. Paste den ind her, hvis det stadig er nødvendigt. Hvis ikke, så luk spørgsmålet.
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