Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- program finalfinalbattleships;
- uses
- SysUtils, StrUtils;
- type
- TShipData = array [1..4] of integer; // x | y | v | t
- TCoordSet = array [0..5,1..2] of integer;
- TGrid = array [1..10, 1..10] of integer;
- var
- grids : array[1..2,1..2] of TGrid;
- currentply : integer;
- procedure printTitle(); // prints 'BATTLESHIPS: ' (GUI).
- var
- n : integer;
- begin
- writeln();
- writeln( 'BATTLESHIPS by Stuart Ashforth' );
- writeln( '------------------------------' );
- for n := 1 to 19 do
- writeln();
- writeln( 'Press enter to continue! ' );
- writeln();
- readln();
- writeln();
- end;
- procedure clearWindow(); // clears the window, avoiding cheating.
- var
- k : integer;
- begin
- for k := 1 to 100 do
- writeln();
- end;
- procedure clearAllGrids(); // sets the 'board' to empty.
- var
- x, y, k : integer;
- grid : TGrid;
- begin
- for k := 1 to 4 do
- begin
- case k of
- 1 : grid := grids[1,1];
- 2 : grid := grids[1,2];
- 3 : grid := grids[2,1];
- 4 : grid := grids[2,2];
- end;
- for y := 1 to 10 do
- begin
- for x := 1 to 10 do
- grid[x,y] := 0;
- end;
- end;
- end;
- function getSymbol( val : integer) : string; // changes data to symbols (GUI).
- var
- sym : string;
- begin
- case val of
- 0 : sym := ' ';
- -1 : sym := 'x';
- -2 : sym := 'o';
- 1 : sym := '&';
- 2 : sym := '/';
- 3 : sym := '=';
- 4 : sym := '+';
- 5 : sym := '%';
- 6 : sym := '&';
- 7 : sym := '/';
- 8 : sym := '=';
- 9 : sym := '+';
- 10 : sym := '%';
- end;
- if sym = '' then sym := intToStr(val);
- sym := sym + ' ';
- getSymbol := sym;
- end;
- function getGrid( ship : TShipData ) : TGrid; // gets the grid a ship should be on.
- var
- id : integer;
- begin
- id := ship[4];
- if id <= 5 then
- getGrid := grids[1,1]
- else
- getGrid := grids[2,1];
- end;
- function getPly( ship : TShipData ) : integer; // gets the player a ship belongs to.
- var
- id : integer;
- begin
- id := ship[4];
- if id <= 5 then
- getPly := 1
- else
- getPly := 2;
- end;
- function idToLength( id : integer ) : integer; // converts a shipID to the length of a ship.
- var
- length : integer;
- begin
- case id of
- 1 : length := 2;
- 2 : length := 3;
- 3 : length := 3;
- 4 : length := 4;
- 5 : length := 5;
- 6 : length := 2;
- 7 : length := 3;
- 8 : length := 3;
- 9 : length := 4;
- 10 : length := 5;
- end;
- idToLength := length;
- end;
- procedure listGrid( ply : integer ); // lists a specific player's board (GUI).
- var
- x, y, c : integer;
- sym : string;
- begin
- writeln( '--------------------------------------------------' );
- writeln( '| | A B C D E F G H I J | A B C D E F G H I J |' );
- writeln( '--------------------------------------------------' );
- for y := 1 to 9 do
- begin
- write( '| ',y,' | ' );
- for x := 1 to 10 do
- begin
- c := grids[ply,1][x,y];
- sym := getSymbol( c );
- write( sym );
- end;
- write( '| ' );
- for x := 1 to 10 do
- begin
- c := grids[ply,2][x,y];
- sym := getSymbol( c );
- write( sym );
- end;
- writeln( '|');
- end;
- write( '| 10 | ' );
- for x := 1 to 10 do
- begin
- c := grids[ply,1][x,10];
- sym := getSymbol( c );
- write( sym );
- end;
- write( '| ' );
- for x := 1 to 10 do
- begin
- c := grids[ply,2][x,10];
- sym := getSymbol( c );
- write( sym );
- end;
- writeln( '|' );
- writeln( '--------------------------------------------------' );
- writeln( '| & : destroyer + : battleship / : submarine |' );
- writeln( '| = : cruiser % : carrier o : miss |' );
- writeln( '| x : hit |' );
- writeln( '--------------------------------------------------' );
- end;
- function createShipData( x, y, v, id : integer ) : TShipData; // composes a TShipData array from its integer parts.
- var
- ship : TShipData;
- begin
- ship[1] := x;
- ship[2] := y;
- ship[3] := v;
- ship[4] := id;
- createShipData := ship;
- end;
- function boolStrToInt( str : string ) : integer; // converts y/n to true/false.
- begin
- if str = 'y' then
- boolStrToInt := 1
- else
- boolStrToInt := 0;
- end;
- function getCoords( ship : TShipData ) : TCoordSet; // gets the set of coordinates corresponding to a particular ship.
- var
- x,y, length, k : integer;
- coords : TCoordSet;
- v : boolean;
- begin
- length := idToLength( ship[4] );
- x := ship[1];
- y := ship[2];
- v := (ship[3] = 1);
- coords[0,1] := length;
- if v then
- begin
- for k := 1 to length do
- begin
- coords[k,1] := x;
- coords[k,2] := y + k - 1;
- end;
- end
- else
- begin
- for k := 1 to length do
- begin
- coords[k,1] := x + k - 1;
- coords[k,2] := y;
- end;
- end;
- getCoords := coords;
- end;
- procedure createShip( ship : TShipData); // actually places the ship on its grid.
- var
- coords : TCoordSet;
- length, id, k, x, y, ply : integer;
- begin
- coords := getCoords( ship );
- ply := getPly( ship );
- length := coords[0,1];
- id := ship[4];
- for k := 1 to length do
- begin
- x := coords[k,1];
- y := coords[k,2];
- grids[ply,1][x,y] := id;
- end;
- end;
- function checkCoords( ship : TShipData ) : boolean; // checks to see if a ship has valid coordinates.
- var
- grid : TGrid;
- coords : TCoordSet;
- x,y, k, length : integer;
- valid : boolean;
- begin
- grid := getGrid( ship );
- coords := getCoords( ship );
- length := coords[0,1];
- valid := true;
- for k := 1 to length do
- begin
- x := coords[k,1];
- y := coords[k,2];
- if valid and ((x > 10) or (x < 1) or (y > 10) or (y < 1)) then
- begin
- valid := false;
- writeln();
- writeln( 'Error: proposed ship is outside the grid!' );
- writeln();
- end;
- if valid and ( not( grid[x,y] = 0 ) ) then
- begin
- valid := false;
- writeln();
- writeln( 'Error: proposed ship intersects with an existing one!' );
- writeln();
- end;
- end;
- checkCoords := valid;
- end;
- function checkValidFormat( inputStr : string ) : boolean; // checks to see if input is like 'A9'.
- var
- valid : boolean;
- xstr, ystr : string;
- y : integer;
- begin
- valid := true;
- if length( inputStr ) = 2 then
- begin
- xstr := inputStr[1];
- ystr := inputStr[2];
- end
- else
- if length( inputStr ) = 3 then
- begin
- xstr := inputStr[1];
- ystr := rightStr( inputStr, 2 );
- end;
- try y := strToInt( ystr );
- except
- valid := false;
- end;
- if (y < 1) or (y > 10) then
- valid := false;
- if valid then
- begin
- valid := false;
- if xstr = 'A' then valid := true;
- if xstr = 'B' then valid := true;
- if xstr = 'C' then valid := true;
- if xstr = 'D' then valid := true;
- if xstr = 'E' then valid := true;
- if xstr = 'F' then valid := true;
- if xstr = 'G' then valid := true;
- if xstr = 'H' then valid := true;
- if xstr = 'I' then valid := true;
- if xstr = 'J' then valid := true;
- if xstr = 'a' then valid := true;
- if xstr = 'b' then valid := true;
- if xstr = 'c' then valid := true;
- if xstr = 'd' then valid := true;
- if xstr = 'e' then valid := true;
- if xstr = 'f' then valid := true;
- if xstr = 'g' then valid := true;
- if xstr = 'h' then valid := true;
- if xstr = 'i' then valid := true;
- if xstr = 'j' then valid := true;
- end;
- checkValidFormat := valid;
- end;
- function stripX( inputStr : string ) : integer; // returns the x coordinate from e.g. 'A9'.
- var
- x : integer;
- xstr : string;
- begin
- xstr := inputStr[1];
- if xstr = 'A' then x := 1;
- if xstr = 'B' then x := 2;
- if xstr = 'C' then x := 3;
- if xstr = 'D' then x := 4;
- if xstr = 'E' then x := 5;
- if xstr = 'F' then x := 6;
- if xstr = 'G' then x := 7;
- if xstr = 'H' then x := 8;
- if xstr = 'I' then x := 9;
- if xstr = 'J' then x := 10;
- if xstr = 'a' then x := 1;
- if xstr = 'b' then x := 2;
- if xstr = 'c' then x := 3;
- if xstr = 'd' then x := 4;
- if xstr = 'e' then x := 5;
- if xstr = 'f' then x := 6;
- if xstr = 'g' then x := 7;
- if xstr = 'h' then x := 8;
- if xstr = 'i' then x := 9;
- if xstr = 'j' then x := 10;
- stripX := x;
- end;
- function stripY( inputStr : string ) : integer; // returns the y coordinate from e.g. 'A9'.
- var
- y : integer;
- begin
- if length(inputStr) = 2 then
- y := strToInt( inputStr[2] );
- if length(inputStr) = 3 then
- y := strToInt( rightStr(inputStr, 2) );
- stripY := y;
- end;
- function idToBoatName( id : integer ) : string; // returns the ship name (e.g. 'destroyer) from a shipID.
- var
- name : string;
- begin
- id := ((id - 1) mod 5) + 1;
- if id = 1 then name := 'destroyer';
- if id = 2 then name := 'submarine';
- if id = 3 then name := 'cruiser';
- if id = 4 then name := 'battleship';
- if id = 5 then name := 'carrier';
- idToBoatName := name;
- end;
- procedure inputBoat ( id : integer ); // gets player input for a ship of a particular shipID.
- var
- x,y,v : integer;
- boatname, vstr, inputStr : string;
- valid : boolean;
- ship : TShipData;
- begin
- repeat
- boatname := idToBoatName( id );
- write( 'Top left coordinate of your ',boatname, ': ');
- readln( inputStr );
- valid := true;
- if checkValidFormat( inputStr ) then
- begin
- x := stripX( inputStr );
- y := stripY( inputStr );
- end
- else
- begin
- writeln();
- writeln( 'That is not a valid coordinate! Example coordinate: A9' );
- writeln();
- valid := false;
- end;
- if valid then
- begin
- write( 'Place ship vertically? (y/n): ' );
- readln( vstr );
- v := boolStrToInt( vstr );
- ship := createShipData( x, y, v, id );
- valid := checkCoords( ship );
- end;
- until valid;
- createShip( ship );
- end;
- procedure setupTitle( ply : integer ); // prints 'Player 1 Setup' (GUI).
- begin
- writeln( '----------------' );
- writeln( 'Player ',ply,' set up:' );
- writeln( '----------------' );
- writeln();
- end;
- procedure playerSetUp( ply : integer ); // gets a player to put his/her ships down.
- var
- n : integer;
- begin
- setUpTitle( ply );
- listGrid( ply );
- for n := (((ply-1)*5) + 1) to (((ply-1)*5) + 5) do
- begin
- writeln();
- inputBoat( n );
- writeln();
- setupTitle( ply );
- listGrid( ply );
- end;
- end;
- function otherPly( ply : integer ) : integer; // returns the player that isn't the current one.
- begin
- otherPly := ( ply mod 2) + 1;
- end;
- procedure turnTitle( ply : integer ); // prints 'Player 1's turn' (GUI).
- begin
- writeln( '----------------' );
- writeln( 'Player ',ply,'''s turn:' );
- writeln( '----------------' );
- writeln();
- end;
- procedure nextPlayerWait(); // the set processes that switch from one player's turn to the other's.
- var
- nextPly : integer;
- begin
- nextPly := otherPly( currentPly );
- writeln();
- writeln( 'Player ',nextPly,'''s turn! Press enter to continue!' );
- writeln();
- readln();
- clearWindow();
- writeln( 'Player ',nextPly,' are you ready? Press enter to continue!' );
- writeln();
- readln();
- currentPly := nextPly;
- end;
- function validMove( x, y, ply : integer) : boolean;
- var
- valid : boolean;
- begin
- valid := true;
- if ((x > 10) or (x < 1) or (y > 10) or (y < 1)) then
- begin
- valid := false;
- writeln();
- writeln( 'Error: proposed target is outside the grid!' );
- writeln();
- end;
- if valid and (not(grids[ply,2][x][y] = 0)) then
- begin
- valid := false;
- writeln();
- writeln( 'Error: target has already been tried!' );
- writeln();
- end;
- validMove := valid;
- end;
- procedure execMove( x, y, ply : integer);
- var
- hit : boolean;
- begin
- hit := false;
- if grids[otherPly(ply),1][x,y] > 0 then
- begin
- grids[otherPly(ply),1][x,y] := -1;
- grids[ply,2][x,y] := -1;
- hit := true;
- end
- else
- grids[ply,2][x,y] := -2;
- turnTitle( ply );
- listGrid( ply );
- if hit then
- begin
- writeln();
- writeln( 'You hit player ',otherPly(ply),'''s ship!' );
- writeln();
- end
- else
- begin
- writeln();
- writeln( 'That was a miss.' );
- writeln();
- end;
- end;
- procedure inputGo( ply : integer);
- var
- x, y : integer;
- inputStr: string;
- valid : boolean;
- begin
- turnTitle( ply );
- listGrid( ply );
- writeln();
- repeat
- valid := true;
- write( 'Desired coordinate of attack: ' );
- readln( inputStr );
- if checkValidFormat( inputStr ) then
- begin
- x := stripX( inputStr );
- y := stripY( inputStr );
- end
- else
- begin
- writeln();
- writeln( 'That is not a valid coordinate!' );
- writeln();
- valid := false;
- end;
- if valid then
- valid := validMove( x, y, ply );
- until valid;
- execMove( x, y, ply );
- end;
- function getPiecesLeft( ply: integer ) : integer;
- var
- grid : TGrid;
- x,y, count : integer;
- begin
- grid := grids[ply,1];
- count := 0;
- for y := 1 to 10 do
- for x := 1 to 10 do
- begin
- if grid[x,y] > 0 then
- count := count + 1;
- end;
- getPiecesLeft := count;
- end;
- begin
- printTitle();
- clearAllGrids();
- currentPly := 1;
- playerSetUp( currentPly ); // set up player 1
- nextPlayerWait();
- playerSetUp( currentPly ); // set up player 2
- nextPlayerWait();
- repeat
- inputGo( currentPly );
- if getPiecesLeft( otherPly( currentPly ) ) = 0 then
- begin
- writeln();
- writeln( 'Congratulations! Player ',currentPly,' has won! :D' );
- writeln();
- currentPly := otherPly( currentPly );
- end
- else
- nextPlayerWait();
- until getPiecesLeft( currentPly ) = 0;
- writeln( 'Game over!' );
- readln()
- end.
Add Comment
Please, Sign In to add comment