Kryžiukai-nuliukai II


Pradinių duomenų failas:
kryziukai.in  
Rezultatų failas:
kryziukai.out  
Laiko apribojimas:
1 s.  
Atminties apribojimas:
16 Mb.  

Užduotis

Parašykite programą, kuri žaistų kryžiukų-nuliukų žaidimą WxH dydžio lentoje (3 ≤ W, H ≤ 10).

Protokolas

Programa turi skaityti duomenis iš standartinio įvesties įrenginio ir rašyti į standartinį išvesties įrengtinį (jokių failų). Programa turi:

  1. perskaityti eilutę su trimis tarpais atskirtais skaičiais W, H ir K. W yra lentelės plotis, H – lentelės ilgis („aukštis“), o K – parametras, kiek simbolių reikia padėti iš eilės (eilutėje, stulpelyje ar įstrižai), kad laimėti;
  2. perskaityti vieną eilutę su vienu simboliu: „x“ arba „o“. Tai žaidėjo (ne kompiuterio) pasirinkimas, ar žaisti kryžiukais, ar nuliukais. Jei įvedama „x“, tai žaidėjas pradeda žaidimą, priešingu atveju – kompiuteris;
  3. esant žaidėjo ėjimui, programa turi perskaityti eilutę su dviem skaičiais x ir y, atskirtais tarpo simboliu. x yra stulpelio, o y – eilutės, kur žaidėjas nori padėti savo simbolį, numeriai;
  4. esant kompiuterio ėjimui, programa turi išspausdinti savo ėjimą tokiu pačiu formatu: viena eilute su dviem tarpo simboliu atskirtais skaičiais;
  5. žaidėjui arba kompiuteriui laimėjus žaidimą, arba lentelėje nelikus nei vieno laisvo langelio, programa turi baigti darbą.

Veikimo pavyzdys (rodyklės vaizduoja, ar duomenys įvedami, ar išvedami):

--> 3 3 3
--> o
<-- 3 3
--> 2 2
<-- 3 2
--> 2 1
<-- 3 1

Šiame pavyzdyje žaidiama standartinėmis kryžiukų-nuliukų taisyklėmis (3 3 3). Kompiuteris žaidžia kryžiukais, pradeda žaidimą, ir laimi, sudėdamas tris kryžiukus trečiajame lentelės stulpelyje.

Vizualizacija

Savo programą galite vizualizuoti šia programa. Todėl svarbu, kad jūsų programa griežtai laikytųsi aprašyto protokolo.

Be to:

  • Po kiekvieno išvedimo veiksmo į standartinį išvedimo įrenginį, atlikite:
    Flush(Output) (Paskaliu), arba
    fflush(stdout) (C), arba
    cout.flush() (C++).
  • Jei testavimo tikslais į ekraną norite išvesti kitos papildomos informacijos, darykite tai tokiu būdu:
    Writeln(StdErr, 'Tai, ką norite išvesti.') (Paskaliu), arba
    fprintf(stderr, "Tai, ką norite išvesti.\n") (C), arba
    cerr << "Tai, ką norite išvesti." << endl (C++).

Vizualizacijos programa parašyta Java platformai ir turėtų veikti bet kokioje OS. Jei programos Windows jums nepaleidžia, o siūlo kitokius (keistus) veiksmus, šalia sukurkite .bat failą su tekstu java -jar kryziukai-gui.jar ir paleiskite jį.

Pavyzdys

Žemiau pateikta programa, kuri nėra korektiška, kadangi netikrina žaidimo pabaigos sąlygų, tačiau ją galite panaudoti įsitikinimui, kad vizualizacija veikia jūsų kompiuteryje, jei programa laikosi aprašytų taisyklių.

program notverysmart;

const MAX = 10; 

var
    taken   : array [1..MAX, 1..MAX] of boolean;
    myturn  : boolean;
    w, h, k,
    x, y    : integer;
    c       : char;

begin
    readln(w, h, k);
    readln(c);
    myturn := c = 'o';
    while true do begin
        if myturn then begin
            { statom į pirmą tuščią langelį }
            x := 1; y := 1;
            while (y <= h) and (taken[x, y]) do
            begin
                y := y + x div w;
                x := 1 + x mod w;
            end;
            if y > h then break;
            taken[x, y] := true;
            writeln(x, ' ', y);
            flush(output);
        end
        else begin
            readln(x, y);
            taken[x, y] := true;
        end;
        myturn := not myturn;
    end
end.

Kaip pateikti šio uždavinio sprendimą

O jei susimąstėte, kaip šitą uždavinį pridėti prie išspręstų, tai štai atsakymas: kai parašysite programą, prieš kurią pačiam nepavyks laimėti, parašykite kitą programą, kuri į nurodytą uždavinio rezultatų failą išvestų eilutę:

Aš sąžiningai isšprendžiau šį uždavinį.

Ir pateikite tą programą kaip šio uždavinio sprendimą. Kieno programa geresnė?

Galite leisti jūsų programoms sužaisti tarpusavyje, paleidę dvi vizualizacijos programas ir atkartodami programų daromus ėjimus.