Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: Pascal: Mastermind Pascalilla

PetriKeckman [27.05.2023 04:42:42]

#

Minkä nuorena oppii sen vanhana taitaa. Koska joskus 100 vuotta sitten 80-luvulla opiskelin HY:ssa tietojenkäsittelyoppia ja opetuskieli oli Pascal, niin varsin kivuttomasti syntyi peli. Ohjelmassa on sälää, mitä tulen käyttämään kun pelaaja valitsee rivin, minkä ohjelma yrittää sitten arvata - nyt siis vain ohjelma arpoo rivin ja pelaaja yrittää arvata. En kyllä tiedä osaanko sitä vaihtoehtoa ohjelmoida ainakaan kivuttomasti, missä ohjelma yrittää arvata pelaajan valitsemaa riviä, tuntuu hankalalta.

Löytyyköhän bugeja? (varmasti löytyy, koska koodi on MINUN aamuyöllä hätäisesti koodaama)

https://petke.info/mastermind.exe (Windows)

Jos 1.6. avattava ohjelmointikilpailu koskee Mastermind peliä, niin tämä koodi kannattanee ehkä poistaa näytiltä?

Täsä freepascal koodi:

program Mastermind;
uses SysUtils;
TYPE varit = 1..6;
VAR merkki: CHAR;
	oikearivi, //syotetty tai ohjelman arpoma oikea rivi
	arvatturivi, //pelaajan arvaama rivi
	ohjelmanrivi: String; //Ohjelman paattelema rivi
	rivit: ARRAY [1..999] OF String; // arvatut tai paatellyt rivit. maxlkm 999
	mahdollisetrivit: ARRAY [1..1296] OF String; // arvatut tai paatellyt rivit. maxlkm 1296
	maxind: 1..999;
	inforivi: String;
	inforivit: ARRAY [1..999] OF String;
FUNCTION oikeatmerkit(rivi: String): BOOLEAN; //tarkistaa ovatko syotetyt merkit 1,2,3,4,5 tai 6
VAR ovat: BOOLEAN;
	ind: 1..5;
BEGIN
	ind:=1;
	ovat:=TRUE;
	REPEAT
		IF (copy(rivi,ind,1)<>'1') AND (copy(rivi,ind,1)<>'2') AND (copy(rivi,ind,1)<>'3') AND (copy(rivi,ind,1)<>'4') AND (copy(rivi,ind,1)<>'5') AND (copy(rivi,ind,1)<>'6') THEN
		BEGIN
			ovat:=FALSE;
			WRITELN('Vain merkit 1,2,3,4,5 tai 6 kelpaavat');
		END;
		ind:=ind+1;
	UNTIL (ovat=FALSE) OR (ind=5);
	oikeatmerkit:=ovat;
END;
FUNCTION rivikelpaa(rivi: String): BOOLEAN;
	VAR kelpaa: BOOLEAN;
BEGIN
	kelpaa:=FALSE;
	IF (Length(rivi)=4) AND (oikeatmerkit(rivi)=TRUE) THEN kelpaa:=TRUE;
	IF (Length(rivi)<>4) THEN WRITELN('Syota neljan merkin pituinen merkkijono');
	rivikelpaa:=kelpaa;
END;
PROCEDURE tarkistarivi(rivi1,rivi2: String); //tulostaa 'p' tai 'v' merkkeja. 'p' merkkeja niin paljon kuin on oikeita vareja oikeilla paikoilla
						//ja 'v' merkkeja niin paljon kuin on oikeita vareja, mutta vaarilla paikoilla.
VAR variind1, variind2, ind: 1..4;
	mrk1,mrk2: String;
	infoapurivi: ARRAY[1..4] OF Char;
	kasiteltyjo: ARRAY[1..4] OF BOOLEAN;
BEGIN
	arvatturivi:=rivit[maxind];
	inforivi:='';
	FOR ind:=1 TO 4 DO
	BEGIN
		infoapurivi[ind]:=' ';
		kasiteltyjo[ind]:=FALSE;
	END;
	FOR variind1:=1 TO 4 DO //tarkistetaan oikean variset oikeassa paikkaa
		IF rivi1[variind1]=rivi2[variind1] THEN
		BEGIN
			infoapurivi[variind1]:='p';
			kasiteltyjo[variind1]:=TRUE;
		END;
	FOR variind1:=1 TO 4 DO //tarkistetaan oikean variset vaarassa paikkaa rivi
		BEGIN
			FOR variind2:=1 TO 4 DO
				BEGIN
					mrk1:=rivi1[variind1];
					mrk2:=rivi2[variind2];
					IF (mrk1=mrk2) AND (kasiteltyjo[variind1]=FALSE) THEN
					BEGIN
						IF (variind1<>variind2) THEN
						BEGIN
							infoapurivi[variind1]:='v';
							kasiteltyjo[variind1]:=TRUE;
							kasiteltyjo[variind2]:=TRUE;
						END;
					END;
				END;
		END;
	FOR ind:=1 TO 4 DO
		IF infoapurivi[ind]='p' THEN inforivi:=inforivi+'p';
	FOR ind:=1 TO 4 DO
		IF infoapurivi[ind]='v' THEN inforivi:=inforivi+'v';
	inforivit[maxind]:=inforivi;
	IF (infoapurivi='    ') THEN WRITELN('Ei mitaan oikein');
	IF (infoapurivi<>'    ') THEN WRITELN(inforivi);
	maxind:=maxind+1;
END;
PROCEDURE pelinvalmistelut;
VAR lkm: 0..4;
	indeksi: 1..4;
	varit, merkkijono: String;
BEGIN
	WRITELN('Mastermind Pelissa yritetaan arvata toisen pelaajan valitsemaa rivia,');
	WRITELN('mika koostuu neljasta kuuden varisesta nappulasta.');
	WRITELN('Valitun rivin varit voivat olla mita tahansa kuudesta');
	WRITELN('(punainen=1, sininen=2, violetti=3, keltainen=4, vihrea=5 tai turkoosi=6');
	WRITELN('Arvaaja laittaa nelja nappulaa pelilaudalle ja saa tiedon, ');
	WRITELN('monta niista on oikealla paikalla (=p) ja monta on oikeaa varia(=v),');
	WRITELN('mutta vaaralla paikalla. Kukin nappula arvioidaan vain kerran.');
	WRITELN('Haluatko olla arvaaja vaiko rivin valitsija (jolloin ohjelma yrittaa paatella valitsemaasi rivia)');
	WRITELN('Vastaa "a" (=arvaaja) tai "v"=valitsija (TAMA VALINTA EI VIELA TOIMI! VOIT SIIS OLLA VAIN ARVAAJA.');
	WRITELN('Syota siis "a")');
	REPEAT
		READLN(merkki);
		IF (merkki <> 'a') AND (merkki <> 'v') THEN WRITELN('Syota "a" tai "v"');
	UNTIL (merkki='a') OR (merkki='v');
	IF merkki='a' THEN WRITELN('Syota rivisi eli neljan merkin pituinen merkkijono, missa merkit ovat "1", "2", "3", "4", "5" tai "6"');

	rivit[1]:=merkkijono;
	maxind:=1; //osoittaa taulukon viimeksi laitettuun riviin
	IF merkki='a' THEN
		BEGIN
			Randomize;
			varit:='123456';
			FOR indeksi:=1 TO 4 DO
				BEGIN
					oikearivi:=oikearivi+varit[Random(6)+1];
					ohjelmanrivi[indeksi]:='?';
				END;
		END;
END;
PROCEDURE luerivi; //syotat rivin
BEGIN
	REPEAT
		READLN(arvatturivi);
	UNTIL rivikelpaa(arvatturivi);
END;
PROCEDURE arvaarivi; //ohjelma arvaa riviä
VAR riviind: 1..999;
	ind: 1..4;
BEGIN
	FOR riviind:=1 TO maxind DO mahdollisetrivit[riviind]:='    ';
	FOR ind:=1 TO maxind DO
	BEGIN
		WRITELN(inforivit[riviind][ind]);
	END;

END;
BEGIN

	IF merkki='v' THEN
	BEGIN
	REPEAT
		BEGIN
			tarkistarivi(oikearivi,arvatturivi);
			arvaarivi;
		END;
	UNTIL  inforivi='pppp';
	END ELSE BEGIN  //olet pelaaja eli arvaaja ja syotit 'a':n
		REPEAT
			pelinvalmistelut;
			REPEAT
				luerivi;
				tarkistarivi(oikearivi,arvatturivi);
			UNTIL inforivi='pppp';
			WRITELN('Onneksi olkoon! Arvasit rivin! :) Syota "k" jos haluat uuden rivin');
			READLN(merkki);
		UNTIL merkki<>'k';
		if merkki='k' THEN WRITELN('Syota rivisi eli neljan merkin pituinen merkkijono, missa merkit ovat "1", "2", "3", "4", "5" tai "6"');
	END;
END.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta