diff --git a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/Edge.class b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/Edge.class deleted file mode 100644 index 8f2be2a..0000000 Binary files a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/Edge.class and /dev/null differ diff --git a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/Element.class b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/Element.class index 3904ea8..e92c92b 100644 Binary files a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/Element.class and b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/Element.class differ diff --git a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/ElementGraph.class b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/ElementGraph.class index d90dfc1..51a96d9 100644 Binary files a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/ElementGraph.class and b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/ElementGraph.class differ diff --git a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/ElementLink.class b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/ElementLink.class index c17b9eb..65a9cef 100644 Binary files a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/ElementLink.class and b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/ElementLink.class differ diff --git a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/Game.class b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/Game.class index 6e31fa2..c74285d 100644 Binary files a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/Game.class and b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/Game.class differ diff --git a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/Graph.class b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/Graph.class deleted file mode 100644 index a801d79..0000000 Binary files a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/Graph.class and /dev/null differ diff --git a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/GraphElement.class b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/GraphElement.class index 7eaeb70..d5133d5 100644 Binary files a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/GraphElement.class and b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/GraphElement.class differ diff --git a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/Player.class b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/Player.class index cd28b11..d7be542 100644 Binary files a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/Player.class and b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/Player.class differ diff --git a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/TamaGolem.class b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/TamaGolem.class index a1269ae..acce035 100644 Binary files a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/TamaGolem.class and b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/TamaGolem.class differ diff --git a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/TamaGolemMain.class b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/TamaGolemMain.class index a8e8a94..4b32820 100644 Binary files a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/TamaGolemMain.class and b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/TamaGolemMain.class differ diff --git a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/WorldBuilder.class b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/WorldBuilder.class index 5d8bf4d..f22256d 100644 Binary files a/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/WorldBuilder.class and b/out/production/TamaGolem/it/arnaldo/unibs/tamagolem/WorldBuilder.class differ diff --git a/src/LinearSystem.java b/src/LinearSystem.java new file mode 100644 index 0000000..cddd80e --- /dev/null +++ b/src/LinearSystem.java @@ -0,0 +1,140 @@ +package it.arnaldo.unibs.tamagolem; + +import java.util.*; + +public class LinearSystem { + private final int n; + private final int m; + private final int[][] A; + private final int[] b; + + public LinearSystem(int n, int[][] A, int[] b) { + this.n = n; + this.m = (n * (n - 1)) / 2; + this.A = A; + this.b = b; + } + + public int[] resolve() { + int[][] extendedMatrix = new int[n][m + 1]; + for (int i = 0; i < n; i++) { + System.arraycopy(A[i], 0, extendedMatrix[i], 0, m); + extendedMatrix[i][m] = b[i]; + } + + int rank = gauss(extendedMatrix); + int indipendentVariables = m - rank; + if (indipendentVariables <= 0) { + throw new IllegalStateException("Sistema determinato o sovradeterminato"); + } + + int[] solutions; + Random rand = new Random(); + int tries = 100000000; + while (tries-- > 0) { + int[] lambdaValues = new int[indipendentVariables]; + for (int i = 0; i < indipendentVariables; i++) { + lambdaValues[i] = (rand.nextInt(n) + 1); // valori tra 1 e 9 + } + + solutions = constructSolution(extendedMatrix, lambdaValues, rank); + if (validNumbers(solutions)) return solutions; + } + + throw new IllegalStateException("Impossibile trovare una solutions intera senza zeri"); + } + + private boolean validNumbers(int[] x) { + boolean positive = false; + boolean negative = false; + for (int xi : x) { + if (xi > 0) positive = true; + else if (xi < 0) negative = true; + if (xi == 0) return false; + } + return positive && negative; + } + + private int[] constructSolution(int[][] extendedMatrix, int[] parameters, int rank) { + int[] x = new int[m]; + Arrays.fill(x, 0); + + List pivotCol = new ArrayList<>(); + boolean[] isFree = new boolean[m]; + Arrays.fill(isFree, true); + + for (int i = 0; i < rank; i++) { + int col = 0; + while (col < m && extendedMatrix[i][col] == 0) col++; + pivotCol.add(col); + isFree[col] = false; + } + + int paramIndex = 0; + for (int i = 0; i < m; i++) { + if (isFree[i]) { + x[i] = parameters[paramIndex++]; + } + } + + for (int i = rank - 1; i >= 0; i--) { + int pivot = pivotCol.get(i); + int val = extendedMatrix[i][m]; + for (int j = pivot + 1; j < m; j++) { + val -= extendedMatrix[i][j] * x[j]; + } + + if (val % extendedMatrix[i][pivot] != 0) { + return new int[m]; // soluzione non intera -> rifiutiamo + } + + x[pivot] = val / extendedMatrix[i][pivot]; + } + + return x; + } + + private int gauss(int[][] mat) { + int row = 0; + for (int col = 0; col < m && row < n; col++) { + int pivot = row; + for (int i = row + 1; i < n; i++) { + if (Math.abs(mat[i][col]) > Math.abs(mat[pivot][col])) { + pivot = i; + } + } + + if (mat[pivot][col] == 0) continue; + + int[] temp = mat[row]; + mat[row] = mat[pivot]; + mat[pivot] = temp; + + for (int i = row + 1; i < n; i++) { + int a = mat[i][col]; + int b = mat[row][col]; + if (a == 0) continue; + + int lcm = lcm(Math.abs(a), Math.abs(b)); + int f1 = lcm / Math.abs(a); + int f2 = lcm / Math.abs(b); + if (a * b < 0) f2 = -f2; + + for (int j = col; j <= m; j++) { + mat[i][j] = mat[i][j] * f1 - mat[row][j] * f2; + } + } + + row++; + } + return row; + } + + private int gcd(int a, int b) { + return b == 0 ? a : gcd(b, a % b); + } + + private int lcm(int a, int b) { + return a / gcd(a, b) * b; + } +} diff --git a/src/TamaGolemMain.java b/src/TamaGolemMain.java index 6cd5764..8df206c 100644 --- a/src/TamaGolemMain.java +++ b/src/TamaGolemMain.java @@ -1,8 +1,11 @@ package it.arnaldo.unibs.tamagolem; + import java.util.*; + public class TamaGolemMain { public static void main(String[] args) { System.out.println("TamaGolem"); WorldBuilder.buildWorld(); + } } \ No newline at end of file diff --git a/src/WorldBuilder.java b/src/WorldBuilder.java index 5811e32..94f44ed 100644 --- a/src/WorldBuilder.java +++ b/src/WorldBuilder.java @@ -7,104 +7,126 @@ public class WorldBuilder { Element[] allElements = Element.values(); Random rand = new Random(); // da cambiare il numero a 8 - int numElements = 3 + rand.nextInt(3); + //int numElements = 3 + rand.nextInt(8); + int numElements = 5; List selectedElements = new ArrayList<>(Arrays.asList(allElements)); Collections.shuffle(selectedElements); selectedElements = selectedElements.subList(0, numElements); ElementGraph world = new ElementGraph(); - HashMap elementStrengthNumber = new HashMap<>(); - HashMap elementStrengthSum = new HashMap<>(); - HashMap elementWeaknessPointToAssign = new HashMap<>(); - HashMap elementWeaknessPoint = new HashMap<>(); - - int numMaxOfPossibleStrength = (numElements * (numElements - 1) / 2) - numElements; - System.out.println(numMaxOfPossibleStrength); - int index = 0; + HashMap> linkDirections = new HashMap<>(); for (Element element : selectedElements) { - index++; - int randomNumber = rand.nextInt(numElements - 2); - if (numMaxOfPossibleStrength - randomNumber < 0) { - randomNumber = numMaxOfPossibleStrength; - numMaxOfPossibleStrength = 0; - } else { - numMaxOfPossibleStrength -= randomNumber; - } - - if (index == numElements) { - randomNumber = numMaxOfPossibleStrength; - } - int strengthNumber = 1 + randomNumber; - int weaknessNumber = numElements - 1 - strengthNumber; - // int strengthSum = Math.max(strengthNumber, weaknessNumber) + rand.nextInt(10); - elementStrengthNumber.put(element, strengthNumber); - elementWeaknessPoint.put(element, weaknessNumber); - } - - - Map graphElementMap = new HashMap<>(); - for (Element el : selectedElements) { - GraphElement ge = new GraphElement(el); - world.addElement(ge); - graphElementMap.put(el, ge); - } - - // Pairing e bilanciamento - List possibleInteractions = new ArrayList<>(); - for (Element attacker : selectedElements) { - for (Element defender : selectedElements) { - if (!attacker.equals(defender)) { - possibleInteractions.add(new Element[]{attacker, defender}); + HashMap links = new HashMap<>(); + Element followingElement = selectedElements.get((selectedElements.indexOf(element) + 1) % selectedElements.size()); + for (Element el : selectedElements) { + if (el == followingElement) { + links.put(el, 1); + } else if (el != element) { + links.put(el, 1); } } + + linkDirections.put(element, links); } - Collections.shuffle(possibleInteractions); + for (Element element : selectedElements) { + HashMap elementLinks = linkDirections.get(element); + for (Element el : selectedElements) { + if (el == element) { + continue; + } - Set alreadyUsed = new HashSet<>(); - - for (Element[] pair : possibleInteractions) { - Element attacker = pair[0]; - Element defender = pair[1]; - - String key = attacker.name() + "-" + defender.name(); - String reverseKey = defender.name() + "-" + attacker.name(); - if (alreadyUsed.contains(key) || alreadyUsed.contains(reverseKey)) continue; - - int attackerRemaining = elementStrengthNumber.get(attacker); - int defenderRemaining = elementWeaknessPoint.get(defender); - - int attackerPoints = elementStrengthSum.get(attacker); - int defenderPoints = elementWeaknessPointToAssign.get(defender); - - if (attackerRemaining <= 0 || defenderRemaining <= 0) continue; - - // Calcolo potenza massima assegnabile - int maxPower = Math.min(attackerPoints - (attackerRemaining - 1), defenderPoints - (defenderRemaining - 1)); - if (maxPower < 1) continue; - - int power = 1 + rand.nextInt(maxPower); - - // Assegna collegamenti - graphElementMap.get(attacker).addLink(new ElementLink(power, defender)); - graphElementMap.get(defender).addLink(new ElementLink(-power, attacker)); - alreadyUsed.add(key); - alreadyUsed.add(reverseKey); - - // Aggiorna contatori - elementStrengthNumber.put(attacker, attackerRemaining - 1); - elementStrengthSum.put(attacker, attackerPoints - power); - - elementWeaknessPoint.put(defender, defenderRemaining - 1); - elementWeaknessPointToAssign.put(defender, defenderPoints - power); +// // controllo anche prima per evitare che magari da un estrazione si vada a togliere +// if (elementLinks.get(el) == 1){ +// linkDirections.get(el).put(element, -1); +// } +// +// if (elementLinks.get(el) == 0) { +// if (Math.random() < 0.5) { +// linkDirections.get(el).put(element, 1); +// } else { +// linkDirections.get(el).put(element, -1); +// } +// } +// +// if (elementLinks.get(el) == 1){ +// linkDirections.get(el).put(element, -1); +// } else { +// linkDirections.get(el).put(element, 1); +// } + } } - System.out.println(numElements); + System.out.println(linkDirections); + + HashMap, Integer> pairIndex = new HashMap<>(); + + int index = 0; + for (int i = 0; i < selectedElements.size(); i++) { + for (int j = i + 1; j < selectedElements.size(); j++) { + Set pair = Set.of(selectedElements.get(i), selectedElements.get(j)); + + pairIndex.put(pair, index++); + } + } + + System.out.println(pairIndex); + + int[][] A = new int[numElements][numElements * (numElements - 1) / 2]; + int[] b = new int[numElements]; + + int i = 0; + for (Element element : selectedElements) { + int[] line = new int[numElements * (numElements - 1) / 2]; + HashMap elementLinks = linkDirections.get(element); + for (Element el : selectedElements) { + if (el == element) { + continue; + } else { + int idx = getIndex(element, el, pairIndex); + line[idx] = elementLinks.get(el); + } + + } + A[i] = line; + b[i] = 0; + i++; + } + + + LinearSystem system = new LinearSystem(numElements, A, b); + + + int[] solution = system.resolve(); + System.out.println("Soluzione trovata:"); + for (int x : solution) { + System.out.printf(String.format("%d ", x)); + } + System.out.println(); + + + + for (Element element : selectedElements) { + GraphElement graphElement = new GraphElement(element); + for (Element el : selectedElements) { + if (el == element) { + continue; + } + //int direction = linkDirections.get(element).get(el); + graphElement.addLink(new ElementLink(solution[getIndex(element, el, pairIndex)], el)); + } + world.addElement(graphElement); + } world.printGraph(); return world; } + private static int getIndex(Element e1, Element e2, HashMap, Integer> pairIndex) { + return pairIndex.get(Set.of(e1, e2)); + } + } +