Kezdőoldal » Számítástechnika » Programozás » Pascal-ban hogyan lehetne...

Pascal-ban hogyan lehetne karakteres felületű sudoku-t csinálni? Hogy kell definiálni?

Figyelt kérdés

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.



2017. okt. 31. 19:18
1 2 3 4
 1/33 anonim ***** válasza:
100%

A szodokuban nem kell semmit tologatni...

[link]


Backtracking algoritmussal lehet generálni érvényes táblákat és a megoldást is lehet azzal előállítani.

2017. okt. 31. 19:28
Hasznos számodra ez a válasz?
 2/33 A kérdező kommentje:

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.

2017. okt. 31. 19:44
 3/33 tabaki ***** válasza:
Az a Sam Loyd féle ezeréves 15-ös játék, semmi köze a szudokuhoz. Mi a problémád a tologatással?
2017. okt. 31. 22:00
Hasznos számodra ez a válasz?
 4/33 tabaki ***** válasza:
2017. okt. 31. 22:06
Hasznos számodra ez a válasz?
 5/33 tabaki ***** válasza:

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?

2017. okt. 31. 22:53
Hasznos számodra ez a válasz?
 6/33 A kérdező kommentje:

Köszönöm a válaszokat.

A "tologatás megvalósítása" a probléma, nem tudom hogy álljak neki.

2017. nov. 1. 05:48
 7/33 coopper ***** válasza:

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.

2017. nov. 1. 07:58
Hasznos számodra ez a válasz?
 8/33 A kérdező kommentje:

Í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.

2017. nov. 1. 09:27
 9/33 coopper ***** válasza:

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.

2017. nov. 1. 10:26
Hasznos számodra ez a válasz?
 10/33 tabaki ***** válasza:

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.

2017. nov. 1. 10:28
Hasznos számodra ez a válasz?
1 2 3 4

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

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!