Table of Contents

1. Descriere

Sokoban este un joc puzzle, creat in 1980 de Hiroyuki Imabashi. Scopul acestui joc este sa transporti cateva obiecte printr-un labirint astfel incat toate obiectele sa ajunga pe zonele marcate. Obiectele, de obicei cutii, pot fi impinse de jucator, una cate una. Jucatorul nu poate impinge doua sau mai multe cutii odata. Pentru a putea fi miscata, o cutie trebuie sa aiba spatiu liber deasupra/dedesubt sau staga/dreapta. Cutia se poate deplasa orizontal sau vertical.

Rezolvarea unui astfel de puzzle este NP-Hard.

2. Hardware

Voi implementa acest joc pe un Atmega16 avand ca intrare un Mouse PS/2 si iesire un LCD de Nokia 3310. Placuta va avea un design minimalist (pe o placa de test 18×24), si va contine un LED rosu de control care sa clipeasca in fiecare secunda.

Piese necesare:

Nume Qty Tip Schema
Atmega16 1 16PU IC
LCD 3310 1 PCD8544 LCD 3310
Mouse PS/2 1 PS/2 MOUSE PS/2
Quartz 1 16MHz Q
Rezistenta 7 1K R1..R7
Rezistenta 6 1K6 R8..R13
Rezistenta 1 10K R14
Rezistenta 2 100ohm R15,R16
Rezistenta 1 2K2 R17
Dioda Zener 2 3V3 D1,D2
Condensator 2 10uF C1,C2
Condensator 3 100nF C3,C4,C5
Condensator 2 15pF C6,C7
Led Rosu 1 rosu LED RED

Schema finala arata asa:

2.1. Programator USB

Nu voi implementa un programator serial doar ca sa scriu bootloader-ul USB. Am folosit placa realizata la laborator (care are programator serial) in acest scop. Alimentarea se va face de la USB.

Cablu pt USB:

Placa facuta la laborator:

Pinout USB:

Pin Name Details pin Atmega16
1 VCC Power 5V 10 - VCC
2 DATA- 17 - PD3
3 DATA+ 16 - PD2
4 GND Ground 11 - GND

2.2. LCD Nokia 3310

Initial am vrut sa folosesc un LCD de Nokia 6100, color, care are nevoie de alimentare speciala pentru backlight (7V). Am decis ca e mai usor sa folosesc un LCD de Nokia 3310, de la Phoenix GSM. Pretul unui astfel de display variaza intre 8 si 30 RON. LCD-ul are nevoie de 3V (+/- 0.3V). Pentru a-i oferi aceasta tensiune folosesc cate un divizor de tensiune cu cate doua rezistente de 1K6 si 1K.

Divizorul de tensiune:

Pinout LCD:

Pin Name Details pin Atmega16
1 VCC Power 2.7-3.3V, needs 1-10uF cap 10 - VCC
2 SCLK Serial clock input 0.0-4.0Mb/s 8 - PB7
3 SDIN Serial data input 7 - PB6
4 D/C Mode (cmd/addr or data) 6 - PB5
5 SCE Chip enable(data clocked), active low 5 - PB4
6 GND Ground 11 - GND
7 VOUT Output voltage, needs 1-10uF cap 11 - GND
8 RES External Reset, active low 4 - PB3

Nu se pot face lipituri direct pe pinii display-ului. Am imprimat in acest scop o placuta care sta lipita de pinii display-ului si este prinsa cu suruburi de acesta. Realizarea placutei a fost dificila, pt ca distanta intre pini este de 1.15mm. Am pus cate un C10uF la masa pt pinii VCC si VOUT.

2.3. Mouse PS/2

Mouse-ul functioneaza la 5V, si am l-am legat direct la pinii Atmega16.

Cablu PS/2:

Mouse PS/2:

Pinout Mouse PS/2:

Pin Name Details pin Atmega16
1 DATA 29 - PC7
2 Not connected
3 GND Ground 31 - AGND
4 VCC Power 5V 30 - AVCC
5 CLK Clock 28 - PC6
6 Not connected

Mama PS/2:

Tata PS/2 este mirrored.

3. Software

3.1 LCD

Am folosit biblioteca grafica de la quantum torque. Aceasta nu foloseste buffer video, si deci consuma putina memorie. Am afisat numai caractere rezolutia fiind de 6×14 caractere. Am sters cateva functii (lcd_clear(), lcd_contrast()…) pentru a ma incadra in 16KB. De asemenea daca nu se foloseste printf/stdio se pot economisi ~2.5KB.

3.2 Mouse

Am pornit de la descrierea protocolului si am facut functiile de scriere si citire pentru mouse. De remarcat urmatoarele:

* se transmit sincron cate 8 biti de date

* Mouse-ul da semnalul de clk, si la scriere si la citire

* pentru initierea transmiterii unui octet, trebuie ca atmega16 sa faca clk “0” pentru cel putin 100usec

* Bitul de transmis de la Mouse la Atmega16 se face pe frontul clk = 0

* In sens invers, de la Atmega16 la Mouse se face cand clk = 1

* pachetul de date contine :

* * 1 bit start (0 sau 1, nu conteaza)

* * 1 octet date (8 biti)

* * 1 bit paritate impara (nr de “1” din octetul de date, par: bit=1 impar: bit=0)

* * 1 bit sfarsit (0 sau 1, nu conteaza)

s.a.m.d

3.3 Sokoban

Harta va fi desenata cu caractere. Cutia este zero (0), tinta este x, iar jucatorul va fi reprezentat sub forma unei sageti (< > ^ v). In functie de cum misc mouse-ul, sageata se modifica corespunzator. Exemplu: Daca deplasamentul pe orizontala > deplasamentul pe verticala, atunci se verifica daca s-a miscat la stanga sau la dreapta. Dupa ce am ales directia, cu click stanga mut jucatorul inainte, impingand eventual o cutie.

Mutare

Am tinut cont de 3 pozitii:

- pozitia cursorului,

- un patrat in fata

- 2 patrate in fata

Orice mutare este determinata de aceste pozitii Am o memorie care retine ultimele 9 mutari, si cu click dreapta pot face undo. Daca la ultima mutare am impins o cutie, se considera 2 mutari - jucator si cutie

Reguli

- jucatorul se poate muta doar in spatiul de joc liber (spatiu,tinta,impinge cutie)

- cutia este impinsa in spatiu liber, dar nu peste alta cutie

- dupa ce am mutat o cutie, verific cate cutii se afla pe tinte

- daca toate cutiile sunt pe tinte trec la nivelul urmator

s.a.m.d

Status

In dreapta hartii de joc se va afisa nivelul curent LVL (momentan 2 nivele implementate), nr de cutii pe pozitia corecta BOX si index mutare din cele 9 mutari memorate MOV.

4. Rezultat

Nu am reusit sa termin proiectul la timp, dar am obtinut rezultatul dorit.

Surse: sokobanlcd3310mouseps2.zip

Nivel 1

Nivel 2

5. Bibliografie

Saru Stefan - 333 CB