home *** CD-ROM | disk | FTP | other *** search
- {$R-}
- {$C-}
- {$K-}
- Program Voter;
-
- Procedure Document;
- {For those of you who do not like machine specific code, I apologize.}
- {But for programs like this, I like speed.}
- Begin
- WriteLn;
- WriteLn(' This program runs the voting simulation described in the Computer');
- WriteLn(' Recreations column of Scientific American of April 1985.');
- WriteLn('');
- WriteLn(' First parameter selects the rule used to determine a cell''s vote:');
- WriteLn(' 0) The rule described in the above mentioned article:');
- WriteLn(' Select a neighbor at random and AGREE with it. (DEFAULT)');
- WriteLn(' 1) Ornery cuss rule: Select a neighbor at random; DISAGREE.');
- WriteLn(' 2) Poll the neighbors. Always go along with the majority.');
- WriteLn(' 3) Poll the neighbors. Go along with majority 99% of the time.');
- WriteLn('');
- WriteLn('The second selects the startup pattern:');
- WriteLn(' 0) Random (DEFAULT)');
- WriteLn(' 1) Checkerboard.');
- WriteLn(' 2) All off.');
- WriteLn(' 3) Use third parameter (between 0.0 and 1.0) to determine');
- WriteLn(' what percentage of the cells begin ON.');
- WriteLn('');
- WriteLn(' No error messages. Leaving out both parameters, gets you this message.');
- WriteLn(' To stop, press control-C TWICE. First time displays number of votes');
- WriteLn(' polled so far; second one aborts the program.');
- WriteLn(' Richard Fritzson');
- {WriteLn(' PO Box 4033');}
- WriteLn(' Madison, WI 53711');
- End;
-
-
- Const
- X = 80; XDim = 79; {Screen Dimensions}
- Y = 23; YDim = 22;
- RuleCnt = 4; {How many rules are there}
- Var
- Count: Real; {Keep count of ballots vote}
- ScrSeg : Integer; {Where is the display screen}
- Rule: Integer; {Which rule to use}
-
- {Return current monitor mode (7 = mono)}
- Function Crtmode : Integer;
- Type
- Register = Record
- Ax,Bx,Cx,Dx,Bp,Si,Ds,Es,Flags : Integer;
- End;
- Var
- Intrregs : Register;
- Begin
- With Intrregs Do Begin
- Ax := $0F00;
- Intr($10,Intrregs);
- Crtmode := Lo(Ax);
- End;
- End;
-
- Procedure Cast(X: Integer; Y:Integer; T:Char);
- {Store vote T in cell X,Y}
- Begin
- Memw[ScrSeg:(160*Y+2*X)] := $0F00+ord(T);
- End;
-
- Function Vote(X,Y:Integer): Char;
- {How does cell X,Y vote?}
- Begin
- Vote := chr(Mem[ScrSeg:(160*Y+2*X)]);
- End;
-
-
- Procedure Initialize; {Setup the universe and the display screen}
-
- Function Ranvote(Start:Integer;P:Real;X,y:Integer): Char;
- {Using rule Start, produce an initial vote for cell X,Y}
- Begin
- Case Start of
- 0: {Random Assignment}
- If Random >= 0.50 Then Ranvote := ' '
- Else Ranvote := #254;
- 1: {Checkerboard pattern}
- If (X mod 2) = (Y mod 2) Then Ranvote := #254
- Else Ranvote := ' ';
- 2: {All blank}
- Ranvote := ' ';
- 3: {P% on}
- If Random >= P Then Ranvote := ' '
- Else Ranvote := #254;
- End;
- End;
-
- Var IX, JY: Integer;
- Start: Integer; {Initial pattern rule}
- Pcnt: Real;
- Begin
- {Interpret command line}
- If ParamCount = 0 Then Begin
- Document;
- Halt;
- End;
-
- Val(Paramstr(1),Rule,IX); {Select a rule from the command line}
- If IX <> 0 Then Rule := 0; {Use 0 by default}
- Rule := Rule mod (RuleCnt + 1);
-
- Val(Paramstr(2),Start,IX); {Select a startup pattern}
- If IX <> 0 Then Start := 0;
- Start := Start mod 4;
-
- If Start = 3 Then Begin {Get user specified decimal fraction}
- Val(Paramstr(3),Pcnt,IX); {Use user's percentage}
- If IX <> 0 Then Pcnt := 0.50;
- End;
- {Initialize screen}
- ClrScr;
- If CrtMode = 7 Then ScrSeg := $B000 Else ScrSeg := $B800;
- Randomize;
- Count := 0.0;
- For IX := 0 To X-1 Do For JY := 0 To Y-1 Do Begin
- Cast(IX,JY,Ranvote(Start,Pcnt,IX,JY));
- End;
- GoToXY(40,24);
- Case Rule of
- 0: Write('Random Neighbor Rule');
- 1: Write('Ornery Cuss Rule');
- 2: Write('Majority Rules');
- 3: Write('99% Majority Rule');
- End;
- GoToXY(63,24);
- Case Start of
- 0: Write('Random Start');
- 1: Write('Checkerboard Start');
- 2: Write('Blank start');
- 3: Write(Pcnt:4:2,'% on start');
- End;
- End;
-
- Procedure ChangeVote0;
- Var I, J: Integer;
- {This implements the standard voting algorithm:
- Select a cell at random.
- Select a neighbor at random.
- Made the cell's new Vote the same as the neighbor's.}
-
- Begin
- Count := Count + 1;
- I := Random(X);
- J := Random(Y);
- Case Random(8) of
- 0: Cast(I,J,Vote((I+X-1 ) mod X ,(J+Y-1 ) mod Y));
- 1: Cast(I,J,Vote((I+X ) mod X ,(J+Y-1 ) mod Y));
- 2: Cast(I,J,Vote((I+X+1 ) mod X ,(J+Y-1 ) mod Y));
- 3: Cast(I,J,Vote((I+X-1 ) mod X ,(J+Y ) mod Y));
- 4: Cast(I,J,Vote((I+X+1 ) mod X ,(J+Y ) mod Y));
- 5: Cast(I,J,Vote((I+X-1 ) mod X ,(J+Y+1 ) mod Y));
- 6: Cast(I,J,Vote((I+X ) mod X ,(J+Y+1 ) mod Y));
- 7: Cast(I,J,Vote((I+X+1 ) mod X ,(J+Y+1 ) mod Y));
- End;
- End;
-
- Procedure ChangeVote1;
- Var I, J: Integer;
- {This implements the ornery cuss rule:
- Select a cell at random.
- Select a neighbor at random.
- Made the cell's new Vote the opposite of the neighbor's.}
-
- Function Disagree(X:Char):Char;
- Begin
- If X = ' ' Then Disagree := #254
- Else Disagree := ' ';
- End;
-
- Begin
- Count := Count + 1;
- I := Random(X);
- J := Random(Y);
- Case Random(8) of
- 0: Cast(I,J,Disagree(Vote((I+X-1 ) mod X ,(J+Y-1 ) mod Y)));
- 1: Cast(I,J,Disagree(Vote((I+X ) mod X ,(J+Y-1 ) mod Y)));
- 2: Cast(I,J,Disagree(Vote((I+X+1 ) mod X ,(J+Y-1 ) mod Y)));
- 3: Cast(I,J,Disagree(Vote((I+X-1 ) mod X ,(J+Y ) mod Y)));
- 4: Cast(I,J,Disagree(Vote((I+X+1 ) mod X ,(J+Y ) mod Y)));
- 5: Cast(I,J,Disagree(Vote((I+X-1 ) mod X ,(J+Y+1 ) mod Y)));
- 6: Cast(I,J,Disagree(Vote((I+X ) mod X ,(J+Y+1 ) mod Y)));
- 7: Cast(I,J,Disagree(Vote((I+X+1 ) mod X ,(J+Y+1 ) mod Y)));
- End;
- End;
-
- Procedure ChangeVote2;
- { This rule implements the "majority rules" rule. When polled,
- each cell ALWAYS adopts the opinion of the majority of his
- neighbors. }
-
- Var I, J: Integer;
-
- Function Survey(I,J:Integer): Char;
- Var K:Integer;
- Begin
- K := 0;
- If Vote((I+X-1 ) mod X ,(J+Y-1 ) mod Y) <> ' ' Then K := K + 1;
- If Vote((I+X ) mod X ,(J+Y-1 ) mod Y) <> ' ' Then K := K + 1;
- If Vote((I+X+1 ) mod X ,(J+Y-1 ) mod Y) <> ' ' Then K := K + 1;
- If Vote((I+X-1 ) mod X ,(J+Y ) mod Y) <> ' ' Then K := K + 1;
- If Vote((I+X+1 ) mod X ,(J+Y ) mod Y) <> ' ' Then K := K + 1;
- If Vote((I+X-1 ) mod X ,(J+Y+1 ) mod Y) <> ' ' Then K := K + 1;
- If Vote((I+X ) mod X ,(J+Y+1 ) mod Y) <> ' ' Then K := K + 1;
- IF Vote((I+X+1 ) mod X ,(J+Y+1 ) mod Y) <> ' ' Then K := K + 1;
- If K > 4 Then Survey := #254
- Else If K < 4 Then Survey := ' '
- Else Survey := Vote(I,J);
- End;
-
- Begin
- Count := Count + 1;
- I := Random(X);
- J := Random(Y);
- Cast(I,J,Survey(I,J));
- End;
-
-
- Procedure ChangeVote3;
- { This rule plays with probabilities:
- 1) survey the neighbors.
- 2) Make it 99% certain the cell will go along
- with the majority. This allows for dissension
- even when all eight neighbors agree.}
-
- Function Survey(I,J:Integer): Char;
- Var K:Integer; Prob : Real;
- Begin
- K := 0;
- If Vote((I+X-1 ) mod X ,(J+Y-1 ) mod Y) <> ' ' Then K := K + 1;
- If Vote((I+X ) mod X ,(J+Y-1 ) mod Y) <> ' ' Then K := K + 1;
- If Vote((I+X+1 ) mod X ,(J+Y-1 ) mod Y) <> ' ' Then K := K + 1;
- If Vote((I+X-1 ) mod X ,(J+Y ) mod Y) <> ' ' Then K := K + 1;
- If Vote((I+X+1 ) mod X ,(J+Y ) mod Y) <> ' ' Then K := K + 1;
- If Vote((I+X-1 ) mod X ,(J+Y+1 ) mod Y) <> ' ' Then K := K + 1;
- If Vote((I+X ) mod X ,(J+Y+1 ) mod Y) <> ' ' Then K := K + 1;
- IF Vote((I+X+1 ) mod X ,(J+Y+1 ) mod Y) <> ' ' Then K := K + 1;
- If K > 4 Then Prob := 0.99
- Else If K < 4 Then Prob := 0.01
- Else Prob := 0.50;
- If Random < Prob Then Survey := #254 Else Survey := ' ';
- End;
-
-
- Var I, J: Integer;
- Begin
- Count := Count + 1;
- I := Random(X);
- J := Random(Y);
- Cast(I,J,Survey(I,J));
- End;
-
- Procedure ChangeVote;
- {Change a single vote using the current rule}
- Begin
- Case Rule of
- 0: ChangeVote0;
- 1: ChangeVote1;
- 2: ChangeVote2;
- 3: ChangeVote3;
- End;
- End;
-
-
- Procedure RunVoterCycle; {Change the voters minds}
-
- Var C: Char; I,J: Integer;
- Begin
- While True Do Begin
- Repeat
- Changevote;
- Until KeyPressed;
- Read(Kbd,C);
- GoToXY(1,24);Write(Count:9:0);
- Read(Kbd,C);
- If C = #03 Then Begin
- ClrScr;
- Halt;
- End;
- GoToXY(1,24);Write(' ');
- End;
- End;
-
- Begin
- Initialize;
- RunVoterCycle;
- End.
-
-