Kirjautuminen

Haku

Tehtävät

Keskustelu: Yleinen keskustelu: Palapelin palasten järjestäminen ennaltamääriteltyyn järjestykseen

sebaloha [24.06.2023 19:52:42]

#

Nyt tarttis javascript-velhoa, joka pystyis jeesaa. Sen verran tärkeä ominaisuus pelissä, et ongelma tarttee ratkaista. Meikäläisen ääöö ei riitä tähän. Tarvittaessa työstä tullaan maksamaan. Katsotaan tarkemmat speksit tämän osalta, kun ollaan käyty projektia tarkemmin läpi.

Kyseessä on liukupalapeli, jossa pelaajilla on mahdollisuus tallentaa pelejä ja jatkaa niitä myöhemmin. Normaalisti ennen kuin peli aloitetaan järjestelmä asettelee palaset satunnaiseen järjestykseen. Kun pelataan tallennettua peliä, pakkaa ei sekoiteta vaan asetellaan palaset tiettyyn järjestykseen.

VAIHE 1: Pelin tallennus

Kun pelaaja tallentaa pelin tsekataan palasten järjestys ja luodaan array-taulukko, joka sisältää palasten tiedot. Itselleni on hieman mysteeriä mistä oikeat tiedot napataan.

Olen kokeillut seuraavia...

1) Tsekataan swappCells-funkkarista palasten tiedot.

// SwappCells saa tiedot shuffle-funkkarista
swapCells(i, j, animate) {
        // console.log(i, j)
        this.cells[i].setPosition(j, animate, i);
        this.cells[j].setPosition(i);
        [this.cells[i], this.cells[j]] = [this.cells[j], this.cells[i]];
        if (!this.shuffling && this.puzzleSolved()) {
          if (this.onFinished && typeof this.onFinished === 'function') {
            this.onFinished.call(this);
          }
        }

        // Tallennetaan palasten tiedot
        let obj = {i: i, j: j}
        this.puzzleArr.push(obj)
      }

2) Tsekataan palasten tiedot objektista

swapCells(i, j, animate) {
       this.cells[i].setPosition(j, animate, i);
       this.cells[j].setPosition(i);
       [this.cells[i], this.cells[j]] = [this.cells[j], this.cells[i]];
       if (!this.shuffling && this.puzzleSolved()) {
         if (this.onFinished && typeof this.onFinished === 'function') {
           this.onFinished.call(this);
         }
       }
       // this.cells
       // {isEmpty: false, index: 3, width: 4000,...}
       // {isEmpty: false, index: 5, width: 4000,...}
       // {isEmpty: false, index: 7, width: 4000,...}

       let x = this.cells[i].index
       let obj = {i: i, j: x}
       this.puzzleArr.push(obj)
     }

3) Tsekataan getPuzzleArr-funkkarista palasten tiedot

getPuzzleArr(){
  const arr = [];
  for(let i = 0; i < this.cells.length; i++){
     const j = this.cells[i].index
     let obj = {i: i, j: j}
          arr.push(obj)
  }
  return arr;
}

VAIHE 2: Pelin aloittaminen

Ladataan tallennettu array selaimen paikallismuistiin.
Luetaan tiedot shuffle-funkkarissa.

shuffle(){
 if(localStorage.getItem('puzzle_game_on') != undefined){
   // Tallennettu array, joka haetaan selaimen paikallismuistista
   const cells = [
          {"i": 8, "j": 8},
          {"i": 7, "j": 3},
          {"i": 6, "j": 3},
          {"i": 5, "j": 2},
          {"i": 4, "j": 0},
          {"i": 3, "j": 1},
          {"i": 2, "j": 2},
          {"i": 1, "j": 0}
      ];

   // const arr= localStorage.getItem('puzzle_saved_game');
   // const cells= JSON.parse(arr);

   for (let i = 0; i < this.cells.length - 1; i++) {
      const j = cells[i].j;
      this.swapCells(i, j);
   }
   this.shuffling = false;
 }else{
   // Järjestä palaset satunnaiseen järjestykseen
   this.shuffling = true;
   for (let i = this.cells.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      this.swapCells(i, j);
   }
   this.shuffling = false;
 }
}

Kokeilin myös määrittää palasten järjestyksen setup-funkkarissa.

setup(){
  if(localStorage.getItem('puzzle_saved_game_on') != undefined){

     // Tallennetut indeksit
     // {isEmpty: false, index: 6, width: 4000,...}
     // {isEmpty: false, index: 4, width: 4000,...}

     const arr = [
            {"i": 0, "j": 6},
            {"i": 1, "j": 4},
            {"i": 2, "j": 5},
            {"i": 3, "j": 1},
            {"i": 4, "j": 0},
            {"i": 5, "j": 2},
            {"i": 6, "j": 7},
            {"i": 7, "j": 3},
            {"i": 8, "j": 8}
        ];


     // const arr = localStorage.getItem('puzzle_saved_game');
     // const cells = JSON.parse(arr);

     for (let i = 0; i < this.dimmension * this.dimmension; i++) {
            this.cells.push(new Cell(this, arr[i].j));
     }

     this.shuffle();
  }else{
    for (let i = 0; i < this.dimmension * this.dimmension; i++) {
       this.cells.push(new Cell(this, i));
    }
   // Luuppaa niin kauan kunnes ratkaistavissa
   while(true){
    this.shuffle();
    const list = this.listOfInds();
    const emptyIndex = this.findEmptyIndexFromBottom(list);
    const N = this.dimmension % 2 == 0 ? true : false;
    const emptyRow = emptyIndex % 2 == 0 ? true : false;
    const solvable = this.isSolvable();

    if(N && emptyRow == true && solvable == false){
      break;
    }else if(N && emptyRow == false && solvable){
      break;
    }else if(N == false && solvable){
      break;
    }
   }
  }
}

Palaset saadaan järjesteltyä uudestaan, mutta lopputulos ei ole oikea.

Koodi kokonaisuudessaan JSFIDDLE

sebaloha [24.06.2023 22:33:14]

#

Vaikuttaa siltä, että swappCells sekoittaa pakkaa. Jos funkkarin deaktivoi, silloin palasten indeksit ovat määritellyn järjestyksen mukaisesti. Miten ihmeessä tämän kohdan ratkaisee?

Metabolix [24.06.2023 22:35:21]

#

Tuossahan on shuffle-kutsu heti sen jälkeen, kun olet yrittänyt jo palauttaa tallennetun järjestyksen. Kumma kun ei toimi?

Olet sekoittanut koodia sen verran paljon, että kannattaa ehkä nollata ja aloittaa uudestaan alkuperäisestä koodista.

Kannattaa tehdä tallennus ja lataus ihan omiin funktioihinsa, suunnilleen seuraavasti:

getState() {
  return {
    numberOfMovements: this.numberOfMovements,
    order: this.cells.map(c => c.index)
  };
}
setState(data) {
  this.numberOfMovements = data.numberOfMovements;
  this.shuffling = true;
  data.order.forEach((cell, pos) => this.cells[pos].index == cell || this.swapCells(pos, this.findPosition(cell)));
  this.shuffling = false;
}

Tämän jälkeen on helppo lisätä vaikka setupin loppuun (tai setup-kutsun jälkeen) lataus:

if (localStorage.getItem("saved")) {
  this.setState(JSON.parse(localStorage.getItem("saved")));
}

Ja vastaavasti vaikka swapCellsin loppuun tallennus:

localStorage.setItem("saved", JSON.stringify(this.getState()));

lainaus:

Tarvittaessa työstä tullaan maksamaan.

Satasella saat täydet oikeudet käyttää edellä olevia koodirivejä.

Muista huomioida myös alkuperäisen koodin lisenssiehdot. (Jos lisenssiä ei löydy, silloinhan koodia ei saa käyttää.)

sebaloha [25.06.2023 11:53:28]

#

Iso kiitos Metabolix! Löysit puuttuvan palasen.

getState-funkkari oli jo olemassa. Tsekkaa viestin alku (getPuzzleArr).

Palasten siirtoja ei tartte tallentaa tässä yhteydessä. Alkuperäisessä koodissa oli jo tähän ratkaisu. Tsekkaa fiddle.

this.totalMoves

Palasten järjestystä ei tartte tallentaa selaimen paikallismuistiin jokaisella siirrolla. Järjestys tsekataan kun pelaaja tallentaa pelin. Tarvittavat tiedot viedään sit kantaan. Tiedot haetaan selaimen paikallismuistiin pelin alussa. Pelin tallennus on mahdollista kun pelaaja on luonut tilin. Ehdottamasi versio ois jees, jos tallennus suoritetaan ainoastaan paikallismuistiin. Pelissä on eri toiminnallisuuksia. Fiddle-koodissa on riisuttu versio.

Ainoa koodirivi jota tartten on:

data.order.forEach((cell, pos) => this.cells[pos].index == cell || this.swapCells(pos, this.findPosition(cell)));

Tässä lopullinen koodi

setup() {
        for (let i = 0; i < this.dimmension * this.dimmension; i++) {
          this.cells.push(new Cell(this, i));
        }

        if(localStorage.getItem('puzzle_saved_game_on') == undefined){
          // Sekoita pakkaa...
        }else{
         // Järjestä tallennetun arrayn mukaan
          const arr = [7,0,8,3,5,2,1,6,4]
          arr.forEach((cell, pos) => this.cells[pos].index == cell.j || this.swapCells(pos, this.findPosition(cell.j)));
        }
      }

JSFIDDLE

Arvostan suuresti apuasi. Satanen on hieman liikaa yhdestä rivistä. Tarjoan 50 egee tästä. Sopiiko?

Vastaus

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

Tietoa sivustosta