Pascal-ban hogyan lehetne karakteres felületű sudoku-t csinálni? Hogy kell definiálni?
Tehát, a tologatást stb miként kell megvalósítani, hogy működjön is?
program sudoku;
var
jatek : array [1..3,1..3] of byte;
i, j, k : byte;
begin
k := 1;
for i := 1 to 3 do
for j := 1 to 3 do
begin
jatek[i,j] := k;
inc(k);
Write(jatek[i,j]:5);
end;
end.
A szodokuban nem kell semmit tologatni...
Backtracking algoritmussal lehet generálni érvényes táblákat és a megoldást is lehet azzal előállítani.
Olyan játékra emlékszem, ahol a számokat tomogatni kellett, volt egy üres négyzet, ennek a helyére lehetett tolni más négyzetet és mindig máshova került az üres hely, így lehetett lassan átrendezni a táblázatot.
Nem tudom akkor milyen játék volt ez.
Khm... biztos, hogy már a tologatásnál tartasz? A programod egyelőre egy sorban írja ki a számokat. A belső ciklus után kell egy vagy két soremelés, tehát a külső ciklus is begin..end közé kerül a több utasítás miatt. A rendesen tördelő változat mondjuk így nézhet ki (nem, mintha a végleges változatban ez pont így bárhol is benne lenne majd):
program tizenotos;
const
OLDAL = 3; // hogy ne kelljen túl sokat matatnod, ha nagyobb négyzetet akarsz
var
jatek : array [1..oldal, 1..oldal] of byte;
i, j, k : byte;
begin
k := 1;
for i := 1 to OLDAL do
begin
for j := 1 to OLDAL do
begin
jatek[i,j] := k;
Inc(k);
Write(jatek[i,j]:5);
end;
WriteLn(#10#13);
end;
end.
Egyébként ez egy jól választott feladat arra, hogy szépen lépésenként építgesd föl. Az is tetszik, hogy láthatólag odafigyelsz a külalakra is. Fog ez menni. Ha javasolhatom, kezeld külön a tömb feltöltését, meg a tábla kirajzolását. Az utóbbit úgyis minden mozgatás után végre kell hajtanod, tehát kell majd egy kirajzoló eljárás, akkor meg miért ne azt használd már az elején is, nem igaz?
Köszönöm a válaszokat.
A "tologatás megvalósítása" a probléma, nem tudom hogy álljak neki.
Szia.
Először is bele kell rakni a táblába a "lyukat" ami általában az utolsó hely szokott lenni (illetve a lyuk helyét le kell tárolni, illetve a lyuk értékét is meg kell határozni).
A "tabaki" programjának a kiirási részét a következővel egésziteném ki a lyuk belerakására :
Ehelyett a sor helyett :
_ _ _ _ Write(jatek[i,j]:5);
inkább ezt :
_ _ _ _ if (jatek[i,j]<>OLDAL*OLDAL)
_ _ _ _ then Write(jatek[i,j]:5)
_ _ _ _ else Write ('_ _ _'); // itt 5 darab szóköznek kell lennie
Igy a 9-ces szám nem kerül kiirásra (illetve az utolsó szám nem kerül kiirásra), ez a szám fogja jelenteni a lyuk helyét a táblázatban.
Most le kell tárolni a lyuk koordinátáit, ugyebár x, y koordinátája van a lyuknak :
LyukX:=OLDAL;
LyukY:=OLDAL;
Csak javasolni tudom én is, hogy fogadd meg "tabaki" mester tanácsát és rakd át metódussá a kiirást, tehát a tömb feltöltést a főprogram is végezheti mig a kiirást egy metódus, mivel ezt többször is meg kell majd hivni.
Most jön a neheze, mivel innentől erőssen forditó függő a dolog:
Lehet billentyűzet lenyomásokat figyelni (ez talán csak a turbó pascalban müködik : readkey), de utánna lehet nézni hogy van-e ilyen függvény az általd használt programban.
Ahol ugyebár a nyilakat kezeled le és annak függvényében, hogy melyik nyilat nyomták le változtatod a LyukX vagy LyukY koordinátáját +1-gyel vagy -1-gyel, figyelsz a minimumra illetve a maximumra is (tehát a LyukX illetve LyukY nem lehet kisebb mint 1 illetve nem lehetnek nagyobbak mint az OLDAL), a LyukX vagy LyukY megváltoztatása után kicseréled a táblázatban az előző LyukX és előző LyukY pozicióban lévő számot a mostani LyukX és LyukY pozicióban lévő számra és meghivod a kiirási metódust ami kiirja az új táblázatot.
Pl ha megnyomták a fel nyilat ami azt jelenti, hogy a lyuknak felfelé kell mozogni, akkor ugyebár cserélni kell
A jatek[2,3] értékét (ami most 6) jatek[3,3] értékre (ami most 9), majd kiiratni a táblázatot.
A másik módszer lehet az ha bekérsz valamilyen számot és ez alapján döntöd el, hogy merre kell mozgatni a lyukat (ez a módszer fapados, de müködik mindegyik forditóval), valahogy igy :
writeln ('Mozgás iránya : 1=Fel, 2=Le, 3=Jobbra, 4=Balra, 9=Kilépés :';
Readln (Irany);
Megvizsgálod, hogy valóban 1,2,3,4 vagy 9 lett beadva, aztán annak függvényében hogy melyik számot adták be változtatod a Lyuk koordinátáiból a megfelelőt (LyukX vagy LyukY) cseréled az előző LyukX illetve LyukY által meghatározott értéket a mostani LyukX és LyukY által meghatározott értékkel és meghivod a kiirási részt.
Szerintem nagyjából ennyi
Sok sikert.
üdv.
Így sikerült, nem tudom a cserén kívül mit sikerült még elnéznem):
program tizenotos;
Uses CRT;
const
OLDAL = 3; // hogy ne kelljen túl sokat matatnod, ha nagyobb négyzetet akarsz
FEL = #72;
LE = #80;
BAL = #75;
Jobb = #77;
var
jatek : array [1..oldal, 1..oldal] of byte;
i, j, k, LyukX, LyukY : byte;
ch : char;
procedure csere (x, y : byte);
var
cs : byte;
begin
cs := jatek[LyukX, LyukY];
jatek[LyukX, LyukY] := jatek[LyukY, LyukX];
Jatek[LyukX, LyukY] := cs;
end;
procedure kiiratas;
var
i, j : byte;
begin
WriteLn;
for i := 1 to OLDAL do
begin
for j := 1 to OLDAL do
begin
if (jatek[i,j]<>OLDAL*OLDAL)
then Write(jatek[i,j]:5)
else Write ('_ _ _'); // itt 5 darab szóköznek kell lennie
end;
WriteLn(#10#13);
end;
end;
begin
k := 1;
for i := 1 to OLDAL do
begin
for j := 1 to OLDAL do
begin
jatek[i,j] := k;
Inc(k);
end;
end;
LyukX := OLDAL;
LyukY := OLDAL;
repeat
kiiratas;
Write (#10#13,'Mozgás iránya : (fel, le, balra, jobbra, Esc =Kilépés) : ');
ch := ReadKey;
if ch = #0 then ch := ReadKey;
case ch of
FEL: begin
if LyukY >1 then begin
dec (LyukY);
csere(LyukY, LyukX);
end
else
begin
sound(1000);
delay(500);
nosound;
LyukY := 1;
end;
end;
LE: begin
if LyukY < OLDAL then begin
inc (LyukY);
csere(LyukY, LyukX);
end
else
begin
sound(1000);
delay(500);
nosound;
LyukY := OLDAL;
end;
end;
BAL: begin
if LyukX > 1 then begin
dec (LyukX);
csere(LyukX, LyukY);
end
else
begin
sound(1000);
delay(500);
nosound;
LyukX := 1;
end;
end;
JOBB: begin
if LyukX < OLDAL then begin
inc (LyukX);
csere(LyukX, LyukY);
end
else
begin
sound(1000);
delay(500);
nosound;
LyukY := OLDAL;
end;
end;
end;
until (ch = #27);
end.
Szia.
A "Csere" szerintem nem jó, mivel ott az előző Lyuk x,y koordinátáinak értékét kell felcserélni a mostani Lyuk x,z koordinátáinak értékeivel, tehát ezeket is le kell tárolni és úgy meghivni a "csere" részt :
LyukX := OLDAL;
LyukY := OLDAL;
Expos := OLDAL; // Előző X pozició
EyPos := OLDAL; // Előző Y pozició
.
.
FEL: begin
if LyukY >1 then begin
EyPos:=LyukY;
dec (LyukY);
csere(LyukY, LyukX, EXPos,EYPos);
end
.
.
Ezt mind a négy nyilnál meg kell tenni (a megfelelő értékekkel), tehát a LE, FEL nyilnál az EYpos-t kell eltárolni (mivel az LyukY fog változni), mig a JOBB, BAL nyilnál az EXPos-t kell eltárolni, mivel a LyukX fog változni.
Ahogyan látod a fenti kódrészletben a cserét négy paraméterrel kell meghivni, tehát a csere procedurát módositani kell (illetve ha paraméteresen hivod meg akkor a paramétereket kellene használni, nem a globális LyukX, LyukY változókat) valahogy igy :
procedure csere (x, y, ex, ey : byte);
var
cs : byte;
begin
cs := jatek[ex, ey];
jatek[ex, ey] := jatek[x, y];
jatek[x, y] := cs;
end;
A kódot nem próbáltam ki, de több gondot nem nagyon látok.
Sok sikert.
üdv.
Nagyon vagány, hogy a 0 után vizsgálandó értékeket akkor is gondosan ellenőrzöd, ha nem kettős kódot kaptál, meg az, hogy minden esetben útmutatást adsz arra is, mit tegyen a program olyan helyzetben, amely nem következhet be. Ezeknél azonban hasznosabb volna a csere megoldása (akár nem is külön eljárásban), mert ez egyelőre nem „elnézés”, hanem a koordinátarendszer át nem gondolása, értelmetlen marhaság.
Közben hol jobban, hol kevésbé érek rá babrálni a kódoddal, úgyhogy egyelőre nem mutatok pontosítást, legalább lesz időd elébe vágni az én változatomnak.
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!