Skip to content

Commit 2dd7963

Browse files
author
MarkGondelman
committed
first commit
0 parents  commit 2dd7963

64 files changed

Lines changed: 6027 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main, master ]
6+
pull_request:
7+
branches: [ main, master ]
8+
9+
jobs:
10+
build:
11+
runs-on: windows-latest
12+
13+
steps:
14+
- uses: actions/checkout@v4
15+
- name: Set up JDK 24
16+
uses: actions/setup-java@v4
17+
with:
18+
java-version: '24'
19+
distribution: 'temurin'
20+
- name: Build with Maven
21+
run: mvn clean compile
22+
- name: Run tests
23+
run: mvn test

.gitignore

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Compiled class file
2+
*.class
3+
4+
# Log file
5+
*.log
6+
7+
# BlueJ files
8+
*.ctxt
9+
10+
# Mobile Tools for Java (J2ME)
11+
.mtj.tmp/
12+
13+
# Package Files #
14+
*.jar
15+
*.war
16+
*.nar
17+
*.ear
18+
*.zip
19+
*.tar.gz
20+
*.rar
21+
22+
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
23+
hs_err_pid*
24+
replay_pid*
25+
26+
# Eclipse
27+
.project
28+
.classpath
29+
.settings/
30+
31+
# IntelliJ IDEA
32+
.idea/
33+
*.iws
34+
*.iml
35+
*.ipr
36+
37+
# NetBeans
38+
nbproject/private/
39+
build/
40+
nbbuild/
41+
dist/
42+
nbdist/
43+
.nb-gradle/
44+
45+
# Maven
46+
target/
47+
48+
# OS generated files
49+
.DS_Store
50+
.DS_Store?
51+
._*
52+
.Spotlight-V100
53+
.Trashes
54+
ehthumbs.db
55+
Thumbs.db
56+
57+
# Temporary files
58+
*.tmp
59+
*.temp

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 Your Name
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# UltraVersenker
2+
3+
A command-line implementation of the classic Battleship game in Java, featuring ANSI-colored console output for an enhanced user experience.
4+
5+
## Features
6+
7+
- Classic Battleship gameplay with human vs AI
8+
- ANSI styling for colorful and formatted console output using the custom Fansi utility
9+
- Keyboard input handling via jnativehook
10+
- Custom rendering system with chaxels (character-based graphics)
11+
- Modular architecture with utilities, game logic, and bridges
12+
13+
## Requirements
14+
15+
- Java 24 or higher
16+
- Maven 3.6+
17+
- Windows (currently, due to CLI launcher specifics)
18+
19+
## Installation
20+
21+
1. Clone the repository:
22+
```bash
23+
git clone https://github.com/yourusername/UltraVersenker.git
24+
cd UltraVersenker
25+
```
26+
27+
2. Build with Maven:
28+
```bash
29+
mvn clean compile
30+
```
31+
32+
## Usage
33+
34+
Run the game directly with Maven:
35+
```bash
36+
mvn exec:java -Dexec.mainClass="JavaBattleShips.UltraVersenker"
37+
```
38+
39+
Or package and run the JAR:
40+
```bash
41+
mvn package
42+
java -jar target/UltraVersenker-1.0-SNAPSHOT.jar
43+
```
44+
45+
The game will launch in a new command prompt window on Windows.
46+
47+
## Project Structure
48+
49+
```
50+
UltraVersenker/
51+
├── src/
52+
│ ├── main/java/
53+
│ │ ├── commonutils/ # Utility classes
54+
│ │ │ ├── Ansi.java
55+
│ │ │ ├── Fansi.java # ANSI styling utility
56+
│ │ │ ├── ParamLine.java
57+
│ │ │ ├── STools.java
58+
│ │ │ └── menudispatcher/ # Menu system utilities
59+
│ │ └── JavaBattleShips/ # Main game package
60+
│ │ ├── bridges/ # Abstractions for input/output
61+
│ │ ├── chaxels/ # Character-based graphics
62+
│ │ ├── chaxelshapes/ # Predefined shapes
63+
│ │ ├── clrender/ # Command-line rendering
64+
│ │ ├── keymaster/ # Keyboard input handling
65+
│ │ ├── logic/ # Game logic and AI
66+
│ │ └── relauncher/ # CLI launcher
67+
│ └── test/java/ # Unit tests
68+
├── pom.xml # Maven configuration
69+
├── README.md # This file
70+
├── .gitignore # Git ignore rules
71+
└── LICENSE # License file
72+
```
73+
74+
## Testing
75+
76+
Run tests with Maven:
77+
```bash
78+
mvn test
79+
```
80+
81+
## Contributing
82+
83+
1. Fork the repository
84+
2. Create a feature branch
85+
3. Make your changes
86+
4. Add tests if applicable
87+
5. Run `mvn test` to ensure everything passes
88+
6. Submit a pull request
89+
90+
## License
91+
92+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
93+
94+
## Acknowledgments
95+
96+
- Uses [jnativehook](https://github.com/kwhat/jnativehook) for global keyboard input
97+
- Custom Fansi library for ANSI console styling</content>
98+
<parameter name="filePath">c:\DevDen\JUC6-Repo\UltraVersenker\README.md

pom.xml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>com.ultraversenker.game</groupId>
8+
<artifactId>UltraVersenker</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
<packaging>jar</packaging>
11+
12+
<properties>
13+
<maven.compiler.source>24</maven.compiler.source>
14+
<maven.compiler.target>24</maven.compiler.target>
15+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
16+
</properties>
17+
18+
<dependencies>
19+
<dependency>
20+
<groupId>com.github.kwhat</groupId>
21+
<artifactId>jnativehook</artifactId>
22+
<version>2.2.2</version>
23+
</dependency>
24+
<dependency>
25+
<groupId>org.junit.jupiter</groupId>
26+
<artifactId>junit-jupiter</artifactId>
27+
<version>5.10.0</version>
28+
<scope>test</scope>
29+
</dependency>
30+
</dependencies>
31+
32+
</project>
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
package JavaBattleShips;
2+
3+
import JavaBattleShips.logic.AIPlayer;
4+
import JavaBattleShips.logic.Board;
5+
import JavaBattleShips.logic.StandardFleet;
6+
import commonutils.Fansi;
7+
import commonutils.STools;
8+
9+
import java.util.*;
10+
11+
public class AIPlayerTest {
12+
private static List<Integer> values = new ArrayList<>();
13+
private static HashMap<String, List<Integer>> allvalues = new HashMap<>();
14+
private static void addValue(Integer value) {
15+
values.add(value);
16+
}
17+
private static void addValue(String key, Integer value) {
18+
19+
if (!allvalues.containsKey(key)) {
20+
allvalues.put(key, new LinkedList<>(values));
21+
}
22+
allvalues.get(key).add(value);
23+
}
24+
25+
private static int medianOf() {
26+
Collections.sort(values);
27+
return values.get(values.size()/2);
28+
}
29+
private static int medianOf(String key) {
30+
List<Integer> list = allvalues.get(key);
31+
Collections.sort(list);
32+
return list.get(list.size()/2);
33+
}
34+
private static int sumOf(List<Integer> list) {
35+
int result = 0;
36+
for (Integer value : list) {
37+
result += value;
38+
}
39+
return result;
40+
}
41+
public static void displayBoard(Board board) {
42+
43+
for (int j = -1; j < board.getHeight(); j++) {
44+
for (int i = -1; i < board.getWidth(); i++) {
45+
if ( j == -1) {
46+
System.out.print((i+1)+" ");
47+
continue;
48+
}
49+
if ( i == -1) {
50+
if ( j == 9) {
51+
System.out.print((j+1));
52+
} else
53+
System.out.print((j+1)+" ");
54+
continue;
55+
}
56+
if ( board.isShip(i,j) ) {
57+
System.out.print("##");
58+
} else {
59+
if ( board.cell(i, j) == Board.DEBRIS) {
60+
System.out.print(Fansi.create().cyan().append("$$").reset().render());
61+
}
62+
if ( board.cell(i, j) == Board.FIRE) {
63+
System.out.print(Fansi.create().red().append("$$").reset().render());
64+
}
65+
if ( board.cell(i, j) == Board.SEA) {
66+
System.out.print(Fansi.create().blue().append("--").reset().render());
67+
}
68+
}
69+
}
70+
System.out.println();
71+
}
72+
}
73+
public static void main(String[] args) {
74+
System.out.println("AIPlayerTest");
75+
Board enemy = new Board(12, 12);
76+
AIPlayer computer; //= new AIPlayer("hard", null);
77+
StandardFleet standardFleet = new StandardFleet();
78+
standardFleet.issueNormal();
79+
standardFleet.randomPlacementOnABoard(enemy);
80+
//computer.uploadBoard(enemy);
81+
Scanner input = new Scanner(System.in);
82+
String init = "easy";
83+
for ( int n = 0; n < 10; n++ ) {
84+
int move = 0;
85+
for ( int l = 0; l < 4; l++) {
86+
float allResult = 0;
87+
switch ( l ) {
88+
case 0: init = "easy"; break;
89+
case 1: init = "normal"; break;
90+
case 2: init = "hard"; break;
91+
case 3: init = "hard+"; break;
92+
}
93+
System.out.print(STools.toLength(init, 10, STools.AL_LEFT) + ">> ");
94+
int best = 1000;
95+
int worst = -1000;
96+
for (int k = 0; k < 1000; k++) {
97+
computer = new AIPlayer(init, null);
98+
enemy = new Board(12,12);
99+
standardFleet.randomPlacementOnABoard(enemy);
100+
computer.uploadBoard(enemy);
101+
move = 0;
102+
do {
103+
move++; //System.out.println("move #"+move);
104+
computer.makeMove(); //System.out.println("computer moved: "+ (computer.getLastX() + 1) + " " + (computer.getLastY() + 1));
105+
//displayBoard(enemy);
106+
if (move > 144) {
107+
System.out.print("Fail! ");
108+
break;
109+
}
110+
} while (!enemy.allShipsDown());
111+
if ( move < best ) best = move;
112+
if ( move > worst) worst = move;
113+
allResult += move;
114+
/* String toOutput = "";
115+
toOutput = FANSI.begin().RGB(250,10, 10).text("" +move).reset().output();
116+
if ( move < 94) {
117+
toOutput = FANSI.begin().RGB(250,100, 100).text("" +move).reset().output();
118+
}
119+
if ( move < 88) {
120+
toOutput = FANSI.begin().RGB(250,150, 100).text("" +move).reset().output();
121+
}
122+
if ( move < 82) {
123+
toOutput = FANSI.begin().RGB(200,150, 150).text("" +move).reset().output();
124+
}
125+
if ( move < 78) {
126+
toOutput = FANSI.begin().RGB(150,200, 255).text("" +move).reset().output();
127+
}
128+
if ( move < 72) {
129+
toOutput = FANSI.begin().RGB(150,150, 255).text("" +move).reset().output();
130+
}
131+
if ( move < 66) {
132+
toOutput = FANSI.begin().RGB(100,150, 255).text("" +move).reset().output();
133+
}
134+
if ( move < 60) {
135+
toOutput = FANSI.begin().RGB(100,100, 255).text("" +move).reset().output();
136+
}
137+
if ( move < 55) {
138+
toOutput = FANSI.begin().RGB(50,150, 255).text("" +move).reset().output();
139+
} //*/
140+
addValue(move);
141+
addValue(init, move);
142+
//if ( move < 100) System.out.print ( "Best: " + best + ", worst: " + worst);
143+
//if ( k % 40 == 39) System.out.println();
144+
}
145+
System.out.print ( "Best: " + best + ", worst: " + worst);
146+
System.out.println(", mean: " + (allResult / 1000) + ", median: " + medianOf());
147+
values = new ArrayList<>();
148+
}
149+
}
150+
for ( String init1 : allvalues.keySet() ) {
151+
System.out.println("all: " + init1 + ", mean: " + (sumOf(allvalues.get(init1)) / (float)(1000 * 10)) + ", median: " + medianOf(init1));
152+
}
153+
}
154+
155+
}
57.1 KB
Binary file not shown.
108 KB
Loading

0 commit comments

Comments
 (0)