Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hands on OOP submission by Naufal Dzaki Imtiyaz #71

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions Naufal Dzaki Imtiyaz_Undip/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Game CLI Based Narto Storm V

## Pejelasan Program
### Deskripsi Program
- Program ini merupakan sebuah game battle sederhana yang berbasi CLI dengan menggunakan bahasa Java.
- User dapat melakukan set player sebagai human ataupun computer.
- Jika player human maka user akan bermain pada game dan melakukan input untuk memberikan aksi pada game.
- Jika player computer maka aksi player tersebut akan dilakukan otomatis oleh sistem.
- Pertarungan yang dapat dilakukan hanya terbatas 2 player saja.
- Dan bisa untuk seluruh player adalah human maupun seluruh player adalah computer.

### Penerapan Konsep OOP
- Inheritance terimplementasikan pada kelas yang memiliki ragam seperti pada kelas Jutsu yang memiliki child class yaitu AttackJutsu dan BuffJutsu.
- Polimorfisme terimplementasikan pada saat membuat instance sebuah Jutsu dan Player.
- Interface terimplementasikan pada interface Player yang nantinya akan diimplemen oleh kelas HumanPlayer dan NonHumanPlayer.

### Penerapan Prinsip SOLID
- Single responsibility Principle
Prinsip ini terimplementasi dimana untuk satu kelas hanya menangani satu tugas saja. Tidak terdapat satu kelas dewa yang menangani semua urusan.
- Open-closed Principle
Prinsip ini terimplementasi dimana untuk menambahkan jenis jutsu yang lain misal UltimateJutsu, kita tidak perlu melakukan modifikasi, cukup lakukan ekstensi dari kelas abstrak Jutsu.
- Dependency Inversion Principle
Prinsip ini terimplementasi dimana untuk kelas yang dependent terhadap kelas lain, ia tidak bergantung pada kelas yang konkrit melainkan sebuah kelas abstrak atau interface.
Seperti pada kelas Shinobi yang dependent terhadap kelas abstrak Jutsu. Serta kelas GameManager yang dependenet terhadap interface Player.

### Penjelasan design pattern yang dipilih
- Disini design pattern yang dipilih adalah **Singleton** dimana terdapat pada class GameManager.
Class tersebut hanya bisa diinstansiasi sebanyak satu kali dan itu berfungsi untuk memulai pertarungan.
Alasan pemilihan design tersebut karena jika terdapat banyak objek dengan kelas tersebut akan sia-sia dan boros resource. Satu saja sudah cukup.
- Kemudian design pattern yang dipilih adalah **Adaptor**
Implementasi tersebut terletak pada kelas StatsEffect dimana merupakan sebuah adaptor untuk kelas Jutsu untuk bisa digunakan oleh kelas Shinobi.
Alasan pemilihan design pattern tersebut adalah agar semua jenis Jutsu hasil turunan dari kelas Jutsu dapat diterima oleh kelas Shinobi
dan tidak memerlukan modifikasi melainkan cukup lakukan ekstensi dari kelas Jutsu.


## Cara Menjalankan Program
1. Clone repository
2. Buka project pada folder yang sudah di clone tadi menggunakan IDE Intellij IDEA (untuk IDE atau text editor lain tidak terjamin aman)
3. Buka file Main.java
4. Lakukan set player 1 dan player 2 ingin sebagai human player atau computer player
5. Pilih karakter dengan memasukkan index list karakter yang sudah disediakan di atas
6. Jalankan program Main.java
7. Selamat bertarung

## Versi Bahasa dan Dependency
Program ditulis menggunakan bahasa Java 19.0.2 dan menggunakan IDE Intellij IDEA.

Kalau dibuka menggunakan VSC entah mengapa terdapat trouble pada saat mengambil inputan dari user.
3 changes: 3 additions & 0 deletions Naufal Dzaki Imtiyaz_Undip/nartoStormV/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions Naufal Dzaki Imtiyaz_Undip/nartoStormV/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Naufal Dzaki Imtiyaz_Undip/nartoStormV/.idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions Naufal Dzaki Imtiyaz_Undip/nartoStormV/nartoStormV.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
281 changes: 281 additions & 0 deletions Naufal Dzaki Imtiyaz_Undip/nartoStormV/src/GameManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,281 @@
import java.util.Scanner;
import java.util.Random;
import java.util.ArrayList;
import java.util.List;
import jutsu.*;
import player.HumanPlayer;
import player.Player;

public class GameManager {
private static GameManager instance;
private List <Player> players;
private boolean isEndGame = false;

private GameManager() {
this.players = new ArrayList<>();
this.players.add(null);
this.players.add(null);
}

public static GameManager getInstance() {
if (instance == null) {
instance = new GameManager();
}
return instance;
}

public void registerPlayer(Player player1, Player player2) {
this.players.set(0, player1);
this.players.set(1, player2);
}

// Start battle game
public void startGame() {
int match = 1;
Player player1 = this.players.get(0);
Player player2 = this.players.get(1);
System.out.println("Game Start!");
System.out.println(player1.getName() + " character : " + player1.getSelectedCharacter().getName());
System.out.println("VS");
System.out.println(player2.getName() + " character : " + player2.getSelectedCharacter().getName());

while (!isEndGame) {
delay(1500);
System.out.println("=====================================");
System.out.println();
System.out.println("Match " + match);
System.out.println();

delay(1500);

System.out.println("-------------------------------------");
System.out.println();
System.out.println(player1.getName() + " character status : ");
player1.getSelectedCharacter().status();
delay(1500);
System.out.println(player2.getName() + " character status : ");
player2.getSelectedCharacter().status();
System.out.println("-------------------------------------");

delay(1500);

System.out.println();
System.out.println(player1.getName() + " turn");

if (player1 instanceof HumanPlayer) {
chooseMoveHuman(player1, player2);
}
else {
delay(2500);
chooseMoveComputer(player1, player2);
}

if (player2.getSelectedCharacter().getHp() <= 0) {
System.out.println(player2.getName() + " loses");
System.out.println(player1.getName() + " wins");
endGame();
break;
}
if (player1.getSelectedCharacter().getHp() <= 0) {
System.out.println(player1.getName() + " loses");
System.out.println(player2.getName() + " wins");
endGame();
break;
}

System.out.println();
delay(1500);
System.out.println("-------------------------------------");
System.out.println();
System.out.println(player1.getName() + " character status : ");
player1.getSelectedCharacter().status();
delay(1500);
System.out.println(player2.getName() + " character status : ");
player2.getSelectedCharacter().status();
System.out.println("-------------------------------------");

delay(1500);

System.out.println();
System.out.println(player2.getName() + " turn");

if (player2 instanceof HumanPlayer) {
chooseMoveHuman(player2, player1);
}
else {
delay(2500);
chooseMoveComputer(player2, player1);
}

if (player1.getSelectedCharacter().getHp() <= 0) {
System.out.println(player1.getName() + " loses");
System.out.println(player2.getName() + " wins");
endGame();
break;
}
if (player2.getSelectedCharacter().getHp() <= 0) {
System.out.println(player2.getName() + " loses");
System.out.println(player1.getName() + " wins");
endGame();
break;
}

match++;

System.out.println();
}

}

// State game over
private void endGame(){
this.isEndGame = true;
System.out.println("Game Over");
}

// Move list player human
private void chooseMoveHuman(Player human, Player opponent) {
Scanner input1 = new Scanner(System.in);
System.out.println("Move list : ");
System.out.println("1. Basic Attack");
System.out.println("2. Jutsu");
System.out.println("3. Chakra Recovery");
System.out.println("4. Surrender");
System.out.println("Choose your move: ");
int move = input1.nextInt();
switch (move) {
case 1:
System.out.println(human.getSelectedCharacter().getName() + " uses basic attack");
human.getSelectedCharacter().basicAttack(opponent.getSelectedCharacter());
break;

case 2:
chooseJutsuHuman(human, opponent);
break;

case 3:
System.out.println(human.getSelectedCharacter().getName() + " healing chakra");
human.getSelectedCharacter().healChakra();
break;

case 4:
System.out.println(human.getName() + " surrenders");
System.out.println(opponent.getName() + " wins");
endGame();
break;

default:
break;
}
}

// Pick jutsu player human
private void chooseJutsuHuman(Player human, Player opponent) {
Scanner input2 = new Scanner(System.in);
System.out.println("Jutsu list : ");
System.out.println("0. Back");
human.getSelectedCharacter().showMasteredJutsu();
Jutsu jutsu;
System.out.println("Choose your jutsu : ");
int choice = input2.nextInt();
switch (choice) {
case 0:
chooseMoveHuman(human, opponent);
break;

case 1:
jutsu = human.getSelectedCharacter().pickMasteredJutsu(choice-1);
System.out.println(human.getSelectedCharacter().getName() + " casts " + jutsu.getName());
human.getSelectedCharacter().castJutsu(jutsu, opponent.getSelectedCharacter());
break;

case 2:
jutsu = human.getSelectedCharacter().pickMasteredJutsu(choice-1);
System.out.println(human.getSelectedCharacter().getName() + " casts " + jutsu.getName());
human.getSelectedCharacter().castJutsu(jutsu, opponent.getSelectedCharacter());
break;

case 3:
jutsu = human.getSelectedCharacter().pickMasteredJutsu(choice-1);
System.out.println(human.getSelectedCharacter().getName() + " casts " + jutsu.getName());
human.getSelectedCharacter().castJutsu(jutsu, opponent.getSelectedCharacter());
break;

default:
break;
}
}

// Move list player computer
private void chooseMoveComputer(Player computer, Player opponent) {
Random rand = new Random();
int move = rand.nextInt(3) + 1;
switch (move) {
case 1:
System.out.println(computer.getSelectedCharacter().getName() + " uses basic attack");
computer.getSelectedCharacter().basicAttack(opponent.getSelectedCharacter());
break;

case 2:
chooseJutsuComputer(computer, opponent);
break;

case 3:
System.out.println(computer.getSelectedCharacter().getName() + " healing chakra");
computer.getSelectedCharacter().healChakra();
break;

case 4:
System.out.println(computer.getName() + " surrenders");
System.out.println(opponent.getName() + " wins");
endGame();
break;

default:
break;
}
}

// Pick jutsu untuk player computer
private void chooseJutsuComputer(Player computer, Player opponent) {
Random rand = new Random();
Jutsu jutsu;
int choice = rand.nextInt(4);
switch (choice) {
case 0:
chooseMoveComputer(computer, opponent);
break;

case 1:
jutsu = computer.getSelectedCharacter().pickMasteredJutsu(choice-1);
System.out.println(computer.getSelectedCharacter().getName() + " casts " + jutsu.getName());
computer.getSelectedCharacter().castJutsu(jutsu, opponent.getSelectedCharacter());
break;

case 2:
jutsu = computer.getSelectedCharacter().pickMasteredJutsu(choice-1);
System.out.println(computer.getSelectedCharacter().getName() + " casts " + jutsu.getName());
computer.getSelectedCharacter().castJutsu(jutsu, opponent.getSelectedCharacter());
break;

case 3:
jutsu = computer.getSelectedCharacter().pickMasteredJutsu(choice-1);
System.out.println(computer.getSelectedCharacter().getName() + " casts " + jutsu.getName());
computer.getSelectedCharacter().castJutsu(jutsu, opponent.getSelectedCharacter());
break;

default:
break;
}
}

// Delay untuk animasi interaktif pada CLI
private void delay(int ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
Loading