siciliaguerrabot2020/SiciliaGuerraBot2020.java (view raw)
1/*
2 * To change this license header, choose License Headers in Project Properties.
3 * To change this template file, choose Tools | Templates
4 * and open the template in the editor.
5 */
6package siciliaguerrabot2020;
7
8import siciliaguerrabot2020.Guerra.Comune;
9import siciliaguerrabot2020.Guerra.Territorio;
10import siciliaguerrabot2020.Guerra.Centroide;
11import java.io.BufferedReader;
12import java.io.File;
13import java.io.FileReader;
14import java.io.IOException;
15import java.util.ArrayList;
16import java.util.Collections;
17import java.util.Scanner;
18import java.util.StringTokenizer;
19import java.util.concurrent.ThreadLocalRandom;
20import picocli.CommandLine;
21import picocli.CommandLine.Option;
22import siciliaguerrabot2020.Calendario.Calendario;
23import siciliaguerrabot2020.Calendario.Data;
24
25/**
26 *
27 * @author Bi-Rabittoh
28 */
29
30public class SiciliaGuerraBot2020 {
31 @Option(names = "-v", description = "verbose output: this only simulates one war (default ${DEFAULT-VALUE})")
32 private boolean verbose = false;
33 @Option(names = "-s", description = "load data from a specific file (default ${DEFAULT-VALUE})")
34 private File source_file = new File("data.txt");
35 @Option(names = "-m", description = "filters for max population (default ${DEFAULT-VALUE})")
36 private int max_population = 12000;
37 @Option(names = "-n", description = "sets number of wars to simulate (default ${DEFAULT-VALUE})")
38 private int n_wars = 500;
39 @Option(names = { "-h", "--help" }, usageHelp = true, description = "display a help message")
40 private boolean helpRequested;
41
42
43 public static void main(String[] args) {
44 /*String[] debug_args = {"-m=50000", "-v"};
45 SiciliaGuerraBot2020 par = CommandLine.populateCommand(new SiciliaGuerraBot2020(), debug_args);*/
46 SiciliaGuerraBot2020 par = CommandLine.populateCommand(new SiciliaGuerraBot2020(), args);
47
48 if(par.helpRequested){
49 CommandLine.usage(par, System.out);
50 System.exit(0);
51 }
52
53 final File file = par.source_file;
54 final int soglia_popolazione = par.max_population;
55 final boolean verbose = par.verbose;
56 final int n_guerre = par.n_wars;
57
58 //LEGGO I DATI DA FILE
59 ArrayList<Comune> comuni_unfiltered = new ArrayList<>();
60 BufferedReader reader;
61 StringTokenizer st;
62 try {
63 reader = new BufferedReader(new FileReader(file));
64 String line = reader.readLine();
65 while (line != null){
66 st = new StringTokenizer(line);
67 comuni_unfiltered.add(new Comune(st.nextToken(), Integer.parseInt(st.nextToken()), new Centroide(Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()))));
68 line = reader.readLine();
69 }
70 } catch (IOException e){
71 System.out.println("File non trovato.");
72 System.exit(1);
73 }
74
75 if(verbose){
76 //FILTRO LE CITTA' PER POPOLAZIONE
77 ArrayList<Comune> comuni = riempiLista(comuni_unfiltered, soglia_popolazione);
78 System.out.println("I comuni in guerra sono " + comuni.size() + ":");
79 for(Comune c : comuni){
80 System.out.println(c.getNome());
81 }
82 System.out.println("\nLa guerra si è conclusa. L'intera regione è adesso unificata sotto il regno di " + combatteteSchiavi(comuni, verbose).getNome() + ".");
83 } else {
84 //ANALIZZO LE PERCENTUALI DI VITTORIA
85 ArrayList<StatComune> statistiche = getStats(comuni_unfiltered, soglia_popolazione, verbose, n_guerre);
86 Collections.sort(statistiche);
87 for(StatComune sc : statistiche){
88 System.out.println(sc.getNome() + ": " + sc.getWinrate(n_guerre) + "%");
89 }
90 }
91 //FINE MAIN
92 System.exit(0);
93 }
94
95 private static Comune combatteteSchiavi(ArrayList<Comune> lista_comuni, boolean verbose){
96 Calendario calendario = new Calendario(new Data(0, 1, 2020));
97 ArrayList<Comune> lista = new ArrayList<>();
98 for(Comune c: lista_comuni){
99 lista.add(new Comune(c.getNome(), c.getPop(), new Centroide(c.getPos().x, c.getPos().y)));
100 }
101 Comune attaccante;
102 Territorio vittima;
103 int vivi = lista.size();
104 int random;
105 boolean esito;
106 Comune propVittima;
107 while(true){
108 //scelgo un comune casuale come attaccante
109 random = ThreadLocalRandom.current().nextInt(0, vivi); //dovrei avere "vivi - 1" ma non serve perchè questa funzione non include l'ultimo valore del range
110 //System.out.println("rand tra 0 e " + (vivi - 1) + ": "+ random);
111 attaccante = lista.get(random);
112 vittima = attaccante.trovaVicino(lista);
113 propVittima = vittima.getProprietario();
114 esito = attaccante.conquista(vittima);
115
116 if(verbose){
117 System.out.print("\n" + calendario.nextString() + ", " + attaccante.getNome() + " ha conquistato il territorio di " + vittima.getNome());
118 if(!propVittima.getNome().equals(vittima.getNome())){
119 System.out.print(" precedentemente occupato da " + propVittima.getNome());
120 }
121 System.out.print(".\n");
122 }
123 if(esito){
124 vivi--;
125 if(verbose)
126 System.out.print(propVittima.getNome() + " è stata completamente sconfitta. " + vivi + " comuni rimanenti.\n");
127 }
128 Collections.sort(lista);
129 if (vivi == 1)
130 break;
131 }
132 return attaccante;
133 }
134
135 public static void pause(){
136 Scanner scanner = new Scanner(System.in);
137 scanner.nextLine();
138 }
139
140 public static void currentStatus(ArrayList<Comune> comuni){
141 for(Comune c : comuni){
142 System.out.println(c.getNome() + ": Territori:");
143 for(Territorio t : c.getTerritori()){
144 System.out.println("\t" + t.getNome());
145 }
146 System.out.println();
147 }
148 System.out.println("\n");
149 }
150
151 public static ArrayList<Comune> riempiLista(ArrayList<Comune> comuni_unfiltered, int soglia_popolazione){
152 ArrayList<Comune> comuni = new ArrayList<>();
153 for(Comune c : comuni_unfiltered){
154 if(c.getPop() >= soglia_popolazione)
155 comuni.add(new Comune(c.getNome(), c.getPop(), new Centroide(c.getPos().x, c.getPos().y)));
156 }
157 return comuni;
158 }
159
160 public static ArrayList<StatComune> getStats(ArrayList<Comune> comuni_unfiltered, int soglia_popolazione, boolean verbose, int n_guerre){
161 ArrayList<Comune> comuni_src = riempiLista(comuni_unfiltered, soglia_popolazione);
162
163 ArrayList<Comune> comuni;
164
165 ArrayList<StatComune> stat = new ArrayList<>();
166 for(Comune c : comuni_src){
167 stat.add(new StatComune(c.getNome()));
168 }
169 String vinc;
170
171 for(int i = 0; i < n_guerre; i++){
172 comuni = new ArrayList<>();
173 for(Comune c : comuni_src){
174 comuni.add(c);
175 }
176 vinc = combatteteSchiavi(comuni, verbose).getNome();
177 for(StatComune sc : stat){
178 if(sc.getNome().equals(vinc)){
179 sc.winWar();
180 break;
181 }
182 }
183 }
184 return stat;
185 }
186}