{"id":16755984,"url":"https://github.com/ptoffy/minimaxlaska","last_synced_at":"2025-08-27T14:08:54.011Z","repository":{"id":158729082,"uuid":"306833681","full_name":"ptoffy/MinimaxLaska","owner":"ptoffy","description":"Laska Game written in C using Minimax AI algorithm.","archived":false,"fork":false,"pushed_at":"2021-08-26T16:18:01.000Z","size":745,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-14T18:56:51.720Z","etag":null,"topics":["c","game","laska","minimax"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ptoffy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-10-24T07:53:46.000Z","updated_at":"2024-01-21T20:48:26.000Z","dependencies_parsed_at":"2023-06-05T01:00:31.129Z","dependency_job_id":null,"html_url":"https://github.com/ptoffy/MinimaxLaska","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ptoffy/MinimaxLaska","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ptoffy%2FMinimaxLaska","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ptoffy%2FMinimaxLaska/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ptoffy%2FMinimaxLaska/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ptoffy%2FMinimaxLaska/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ptoffy","download_url":"https://codeload.github.com/ptoffy/MinimaxLaska/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ptoffy%2FMinimaxLaska/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272338924,"owners_count":24917058,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-27T02:00:09.397Z","response_time":76,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","game","laska","minimax"],"created_at":"2024-10-13T03:24:29.351Z","updated_at":"2025-08-27T14:08:54.004Z","avatar_url":"https://github.com/ptoffy.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Progetto Lasca\nGruppo 52 - Paul Toffoloni\n\n## Introduzione\n\nLasca è una variante della Dama, ideato dallo scacchista tedesco Emanuel Lasker nel 1911;\nè noto anche come Laska o semplicemente come Lasker, o anche Laskers.\nSi gioca con le stesse regole della Dama, ma su un campo di sole 49 caselle (7 per lato).\nI pezzi catturati non vengono rimossi dal campo, ma trascinati e sormontati dal pezzo catturante.\n\n## Struttura\n\u003e All'interno della documentazione di Doxygen si possono trovare degli schemi che mostrano\n\u003e la struttura del progetto a livello grafico in modo da facilitare la lettura.\n\nIl programma è strutturato in diversi Abstract Data Types (ADT).\n### struct\n- **Board**: Il campo da gioco, contenente una matrice fissa di Cell;\n- **Cell**: Una singola cella del campo da gioco, contenente delle coordinate x e y (int) ed eventualmente una Tower;\n- **Piece**: Un singolo pezzo di gioco, caratterizzato da colore e tipo (soldier o officer);\n- **Tower**: Una torre, ovvero un array di Piece, ciò che viene usato in realtà giocando, caratterizato da un'altezza,\n  un Color e un Type, questi ultimi due indicati dal colore e dal tipo della prima pedina della torre,\n  ovvero quella che controlla la torre;\n- **Move**: Una singola mossa, contenente le Cell di origine e destinazione ed eventualmente una Cell da mangiare;\n- **Moves**: Una raccolta di Move che serve nel momento in cui dobbiamo calcolarci le possibili mosse.\n\n### enum\n- **Type** `{SOLDIER = 0, OFFICER = 1}`: rappresenta il tipo di pedina, quindi se è una dama o no;\n- **Color** `{WHITE = 0, BLACK = 1}`: rappresenta il colore di una pedina;\n- **bool** `{false = 0, true = 1}`: siccome in ANSI C non esiste bool e non si può importare `\u003cstdbool.h\u003e`\n  ho creato un enum per simulare il tipo booleano.\n\nOgni struttura è a conoscenza esclusivamente dei suoi parametri e non conosce dati di altre strutture,\nseguendo il principio dell'incapsulamento per accederci utilizza metodi come getter e setter,\ncreati all'interno di ogni struttura. Purtroppo C non è un linguaggio ad oggetti quindi non si può seguire un approccio\nad oggetti \"tradizionale\" ma bisogna applicare dei metodi alternativi, per esempio al posto delle classi verranno usate\ndelle struct.\n\nOgni funzione è il più possibile astratta con l'obiettivo del riuso del codice, di conseguenza la struttura\nproposta è anche estremamente estendibile ed è molto semplice implementare nuove funzionalità senza dover né\nmodificare né conoscere per filo e per segno ogni riga del codice già scritto.\n\n## Funzionalità\n\nIl gioco, funzionante su terminale, presenta un menù con il quale l'utente può scegliere\nse giocare contro un altro giocatore, contro il computer o uscire. Dopodichè, il gioco comincerà.\n\nPer giocare, il codice è estremamente user friendly e allo stesso tempo limitato: non permette all'utente di fare\nscelte sbagliate che potrebbero andare a creare problemi, come per esempio immissione di coordinate sbagliate: sarà\nil programma che proporrà all'utente quali mosse sono disponibili e gliene farà scegliere una. Ovviamente l'inserimento\ndella scelta da parte dell'utente è controllata e non permette l'inserimento errato di mosse.\nUna volta scelta la mossa, sarà il sistema a preoccuparsi del resto, muovendo la pedina ed eventualmente\nmangiando, se è una mossa di conquista. Anche per quanto riguarda queste ultime, sarà il sistema ad accorgersi\nse è possibile mangiare, e presenterà all'utente solo tali mosse. Infine, il gioco continuerà e cambierà turno,\na me no che non ci siano più mosse disponibili per colui che deve giocare il turno, in quel caso la partita finirà.\n\nPer il giocatore singolo, è stato implementato l'algoritmo Minimax in modo che la CPU possa fare delle scelte\ncon un certo criterio.\n\n### MiniMax\n\n1. Crea un albero sulla base delle mosse disponibili, ogni livello di questo albero conterrà le mosse che un\n   giocatore (sia CPU sia utente) può svolgere.\n2. Attraversa ricorsivamente l'albero creato, assegnando ad ogni mossa un valore, valutato sulla base del vantaggio\n   che può portare alla CPU. Il valore è calcolato nella funzione `evaluate(Board *board)` e si basa sul numero di pezzi\n   presenti sul campo da gioco dopo aver simulato una mossa, quindi indica se ci sono state delle mangiate o no\n   e a favore di chi. Inoltre, tarato con meno importanza, c'è anche la quantità di pedine `Officer` presenti, quindi\n   anche la possibilità di promuovere una pedina ha ruolo nella valutazione. Più il numero è alto, più e vantaggioso\n   per il giocatore.\n3. Sceglie, per ogni livello, la mossa più conveniente comparando i valori delle varie mosse, a seconda del turno che\n   si sta controllando si sceglierà il numero più alto (se il turno è lo stesso della CPU) oppure il numero più basso se\n   il turno controllato è dell'utente.\n\n![image](https://upload.wikimedia.org/wikipedia/commons/thumb/6/6f/Minimax.svg/400px-Minimax.svg.png)\n\nPiù la depth della AI è alta, quindi il numero di turni e di conseguenza il numero di mosse controllati, più l'AI\nci metterà a trovare un risultato. La complessità computazionale è **O(b^m)**, dove b è il numero di mosse possibili\nper ogni turno ed m è il numero massimo di profondità (depth).\n\n## Possibili miglioramenti\n- **Multi-mangiata**: Non è ancora possibile svolgere più mangiate in una mossa sola. Per implementare ciò servirebbe\n  semplicemente aggiungere un ciclo o addirittura una ricorsione nella funzione che si occupa di controllare la mossa\n  e di svolgere la mangiata;\n- **GUI**: attraverso librerie grafiche come GTK oppure SDL si può aggiungere una interfaccia grafica molto più piacevole\n  per l'utente.\n- **Alpha-Beta Pruning**: Tecnica che permette di diminuire la complessità computazionale dell'algoritmo Minimax.\n\n## Difficoltà incontrate\nPersonalmente la difficoltà più grande è stata quella di abituarsi ad un linguaggio di programmazione\ndi basso livello come C, essendo normalmente abituato ad usare Java, Swift e altri linguaggi che non necessitano di\ngestione della memoria manuale. In più, C non è neanche un linguaggio ad oggetti, di conseguenza strutturare un progetto\ndel genere senza usare gli oggetti, ha allungato di molto i tempi, siccome ho cercato comunque\ndi seguire le best practices di incapsulamento, astrazione ed information hiding.\nLa cosa più interessante è stata senza dubbio l'implementazione dell'algoritmo Minimax per giocare contro la CPU.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fptoffy%2Fminimaxlaska","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fptoffy%2Fminimaxlaska","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fptoffy%2Fminimaxlaska/lists"}