[์ฐํ ์ฝ 5๊ธฐ] <4์ฃผ์ฐจ> 'java-bridge' ํ๊ณ
<์ฐ์ํ ํ ํฌ์ฝ์ค 5๊ธฐ ํ๋ฆฌ์ฝ์ค ์งํ์ฌํญ - 4์ฃผ์ฐจ>
๐จ๐ป๐ป๋ง์ง๋ง ์ฃผ์ฐจ์ธ 4์ฃผ์ฐจ์์๋ java-bridge๋ผ๋ ์ฃผ์ ๋ก ๊ณผ์ ๋ฅผ ์ํํ๊ฒ๋์๋ค.
์ ์ ์์ด ๊ณผ์ ๋ฅผ ์ํํ๋ค๋ณด๋ ๋ฒ์จ 4์ฃผ์ฐจ๊ฐ ๋์ด์์๊ณ , ํ๋ฌ ๊ฐ ์๋กญ๊ฒ ๋ฐฐ์ด ์ฌ์ค์ด ๋ง์์ ๋ฟ๋ฏํ๋ค.๐ก
<๋ฐฑ์๋ - Java> ๊ธฐ์ค์ผ๋ก ๊ณผ์ ๋ฅผ ์ํํ์๋ค.
<๋ค๋ฆฌ ๊ฑด๋๊ธฐ>
- ๊ธฐ๋ฅ ์๊ตฌ ์ฌํญ
- ์์๋ ๋ ์ค ํ๋์ ์นธ๋ง ๊ฑด๋ ์ ์๋ ๋ค๋ฆฌ๋ฅผ ๋๊น์ง ๊ฑด๋๊ฐ๋ ๊ฒ์์ด๋ค.
- ์ ์ถ๋ ฅ ์๊ตฌ ์ฌํญ
- ํ๋ก๊ทธ๋๋ฐ ์๊ตฌ ์ฌํญ
๊ทธ ์ธ๋ก InputView ํด๋์ค, OutputView ํด๋์ค,
BridgeGame ํด๋์ค, BridgeMaker ํด๋์ค, BridgeRandomNumbergenerator ํด๋์ค ๋ํ ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์กฐ๊ฐ ์ฃผ์ด์ก๋ค.
- ๊ตฌํ๊ณผ์
์ ์ฃผ์ฐจ์ ๊ฐ์ ์ ํ์ฌํญ์ด ์ฃผ์ด์ก๊ณ , ์ด๋ฒ์๋ ํด๋์ค์ ์ธ๋ถํ๊ฐ ํ์ํ ๊ฒ ๊ฐ์๋ค.
๋ค๋ง ์ด๋ฒ์๋ ์ถ๋ ฅํ๋ OutputView ๋ถ๋ถ์ด ๋งค์ฐ ์ค์ํ ๊ฒ ๊ฐ์๋ค. ์ด๋ํ๋ ๋ถ๋ถ์ ์ ๋ฐ์ดํธํ์ฌ ํ๋ฉด์ ๋ณด์ฌ์ฃผ๊ณ ,
์ฌ์ฉ์๊ฐ ๊ฐ๋ ๋ฐฉํฅ์ ๋ฐ๋ผ ๋ค๋ฅธ ์ถ๋ ฅ๊ฐ์ ํ์ํด์ผ๋๊ธฐ ๋๋ฌธ์ ๋ ์ด๋ ค์ด ๊ฒ ๊ฐ์๋ค.
<Application.java>
package bridge;
public class Application {
public static void main(String[] args) {
// TODO: ํ๋ก๊ทธ๋จ ๊ตฌํ
final BridgeGame bridgeGame = BridgeGame.create();
bridgeGame.move();
}
}
- Application.java์์ BridgeGame์ ์ฐธ์กฐํ์ฌ move() ๋ฉ์๋๋ฅผ ํตํด ๊ฒ์์ ์งํ์ํฌ ์ ์๋๋ก ํ์๋ค.
<BridgeGame.java>
package bridge;
import java.util.List;
/**
* ๋ค๋ฆฌ ๊ฑด๋๊ธฐ ๊ฒ์์ ๊ด๋ฆฌํ๋ ํด๋์ค
*/
public class BridgeGame {
static int bridge_size = InputView.readBridgeSize();
static String final_result;
static int final_count;
static String map_move;
BridgeGame(){
}
public static BridgeGame create(){
return new BridgeGame();
}
/**
* ์ฌ์ฉ์๊ฐ ์นธ์ ์ด๋ํ ๋ ์ฌ์ฉํ๋ ๋ฉ์๋
* <p>
* ์ด๋์ ์ํด ํ์ํ ๋ฉ์๋์ ๋ฐํ ํ์
(return type), ์ธ์(parameter)๋ ์์ ๋กญ๊ฒ ์ถ๊ฐํ๊ฑฐ๋ ๋ณ๊ฒฝํ ์ ์๋ค.
*/
public void move() {
String direction = InputView.readMoving();
List<String> Bridge_path = BridgeMaker.makeBridge(bridge_size);
int i = 0; int count = 0;
while(i == (bridge_size*2)) { // ๋๊น์ง ๋๋ฌํ ๋๊น์ง ๋ฐ๋ณต
if (direction == "U") { // "U"์ ์
๋ ฅํ์๊ณ , ์ ๋ต์ด๋ฉด, ๋ค์์นธ์ผ๋ก
if (Bridge_path.get(i) == direction) { i += 2; count++; map_print("O"); direction = InputView.readMoving();
} else map_print("X"); retry();
} else if (direction == "D") { // "D"๋ฅผ ์
๋ ฅํ์๊ณ , ์ ๋ต์ด๋ฉด, ๋ค์์นธ์ผ๋ก
if (Bridge_path.get(i) == direction) { i += 2; count++; map_print("O"); direction = InputView.readMoving();
} else map_print("X"); retry();
}
}
if(i >= (bridge_size*2)) success("์ฑ๊ณต", count);
}
public static void success(String result, int count){
final_result = result;
final_count = count;
}
public static void map_print(String is_success){
map_move = is_success;
}
public static String map_move(){
return map_move;
}
public static String endgame_1(){
return final_result;
}
public static int endgame_2(){
return final_count;
}
/**
* ์ฌ์ฉ์๊ฐ ๊ฒ์์ ๋ค์ ์๋ํ ๋ ์ฌ์ฉํ๋ ๋ฉ์๋
* <p>
* ์ฌ์์์ ์ํด ํ์ํ ๋ฉ์๋์ ๋ฐํ ํ์
(return type), ์ธ์(parameter)๋ ์์ ๋กญ๊ฒ ์ถ๊ฐํ๊ฑฐ๋ ๋ณ๊ฒฝํ ์ ์๋ค.
*/
public void retry() {
String game_choice = InputView.readGameCommand();
boolean result = true; // ์ฑ๊ณต
if(game_choice == "R") create();
else if(game_choice == "Q") success("์คํจ", final_count);
}
}
- BridgeGame๋ถ๋ถ์ด ์ด ๊ณผ์ ์์ ๊ฐ์ฅ ํต์ฌ๋ถ๋ถ์ด์๋๋ฐ, ์ฝ๋๋ฅผ ์์ฑํ ์๋ก ์คํ๊ฒํฐ์ฝ๋์ฒ๋ผ ๋ง์ด ์ฝํ๋ ๊ฒ์
ํ์ธํ ์ ์์๋ค. ๊ตฌํ์ ์ด์ ์ ๋๋ค๋ณด๋ ๋์ค์๋ ์ด๋์๋ถํฐ ๊ณ ์ณ์ผํ ์ง ๊ฐ์ด ์กํ์ง ์๊ธฐ๋ํ์ฌ์
์ถํ ๋ค๋ฅธ ํ๋ก์ ํธ๋ฅผ ์งํํ ๋๋ ๊ตฌ์กฐ๋ถํฐ ์ค๊ณํ๊ณ ๊ทธ์ ๋ง๊ฒ ํด๋์ค๋ฅผ ์์ฑํด์ผ๊ฒ ๋ค๊ณ ๋๊ผ๋ค.
move()๋ฉ์๋์์๋ direction์ผ๋ก InputView์์ ์ ๋ ฅ๋ฐ์ ๊ฐ์ผ๋ก ๋ฐฉํฅ์ ์ ํ๊ณ ,
Bridge_path๋ฅผ ํตํด ์์ฑ๋ ๋ค๋ฆฌ๋ฅผ ์ฐธ์กฐํด์จ๋ค.
while๋ฌธ์ ํตํด bridge_size์ ๋๋ฌํ ๋๊น์ง direction์์ ์ ๋ ฅ๋ฐ๋ ๋ถ๋ถ์ ์ฒ๋ฆฌํ๋ค.
"U" = ์ / "D" = ์๋
์ ๋ ฅ๋ ๋ฐฉํฅ์ด ์ ๋ต์ผ ๊ฒฝ์ฐ์๋
if (Bridge_path.get(i) == direction) {
i += 2;
count++;
map_print("O");
direction = InputView.readMoving();
}
์ฒ๋ผ ์ฆ๊ฐ๊ฐ์ ์ฒ๋ฆฌํ๊ณ , map_print๋ฅผ ํตํด ํ๋ฉด์ O๋ฅผ ์ถ๋ ฅํ๊ณ ์ ํ์๋ค.
if๋ฌธ ์์ ์ด 4์ค์ ์ฝ๋๊ฐ ๋ค์ด์์์ผ๋, ํจ์ ๋ด 15์ค ์ ํ์ฌํญ์ ๋ง์ถ๊ธฐ ์ํ์ฌ ํ ์ค๋ก ๋ง์ถฐ๋๊ธฐ๋ํ์ง๋ง,
๋งค์ฐ ๋นํจ์จ์ ์ธ ๊ฒ ๊ฐ์๊ณ ์ด ํด๋์ค๋ฅผ ๋ ์ชผ๊ฐ์ด ๊ด๋ฆฌํ์์ผ๋ฉด ์ด๋ ์๊นํ๋ ์๊ฐ๋ ํ๊ฒ๋์๋ค.
์ ๋ต์ด ์๋ ๊ฒฝ์ฐ์๋
else map_print("X"); retry();
์ฒ๋ผ map_print๋ฅผ ํตํด ํ๋ฉด์ X๋ฅผ ์ถ๋ ฅํ๊ณ retry()๋ฅผ ํธ์ถํ์ฌ ์ฌ์์ํ ์ ์๋ ๋ฌธ๊ตฌ๊ฐ ๋ฐ ์ ์๋๋ก ๊ตฌํํ์๋ค.
retry() ๋ฉ์๋์์
game_choice ๋ณ์๋ฅผ ํตํด ์ฌ์์ํ ๊ฒ์ธ์ง, ์ข ๋ฃํ ๊ฒ์ธ์ง ์ ๋ ฅ์ ๋ฐ๊ณ ,
"R"์ด๋ฉด ์ฌ์์์ด๋ฏ๋ก create()๋ฅผ ํตํด BridgeGame ํด๋์ค๋ฅผ ์ฌํธ์ถํ์๊ณ ,
"Q"๊ฐ ์ ๋ ฅ๋์์ผ๋ฉด ์ข ๋ฃ์ด๋ฏ๋ก, ์ฑ๊ณต์ฌ๋ถ ํ๋จ ํ "์คํจ" ๋ฉ์์ง์ ํจ๊ป ํ๋ก๊ทธ๋จ์ด ์ข ๋ฃ๋๋๋ก ๊ตฌํํ์๋ค.
<BridgeMaker.java>
package bridge;
import java.util.ArrayList;
import java.util.List;
import bridge.BridgeRandomNumberGenerator;
/**
* ๋ค๋ฆฌ์ ๊ธธ์ด๋ฅผ ์
๋ ฅ ๋ฐ์์ ๋ค๋ฆฌ๋ฅผ ์์ฑํด์ฃผ๋ ์ญํ ์ ํ๋ค.
*/
public class BridgeMaker {
private final BridgeNumberGenerator bridgeNumberGenerator;
public BridgeMaker(BridgeNumberGenerator bridgeNumberGenerator) {
this.bridgeNumberGenerator = bridgeNumberGenerator;
}
/**
* @param size ๋ค๋ฆฌ์ ๊ธธ์ด
* @return ์
๋ ฅ๋ฐ์ ๊ธธ์ด์ ํด๋นํ๋ ๋ค๋ฆฌ ๋ชจ์. ์ ์นธ์ด๋ฉด "U", ์๋ ์นธ์ด๋ฉด "D"๋ก ํํํด์ผ ํ๋ค.
*/
public static List<String> makeBridge(int size) {
List<String> bridge = new ArrayList<>();
int temp; String correct_direction;
for(int i = 0; i < size; i++){
temp = BridgeRandomNumberGenerator.generate_num();
if(temp == 1) {
correct_direction = "U";
bridge.add(i, correct_direction); }
else if(temp == 0) {
correct_direction = "D";
bridge.add(i, correct_direction); }
} return bridge;
}
}
- BridgeMaker๋ ๋ง๊ทธ๋๋ก ๋ค๋ฆฌ๋ฅผ ์์ฑํ๋ ๋ถ๋ถ์ธ๋ฐ, ๋ค๋ฆฌ์ ๊ธธ์ด์ ๋ฐ๋ผ U, D ๋ฐฉํฅ์ผ๋ก ๋ค๋ฆฌ๋ฅผ ์ถ๊ฐํด๋๊ฐ๋ค.
<BridgeNumberGenerator.java>
package bridge;
@FunctionalInterface
public interface BridgeNumberGenerator {
int generate();
}
- ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ค์ด generate๋ฅผ ํจ๊ณผ์ ์ผ๋ก ํธ์ถํ ์ ์๋๋ก ํ์๋ค.
<BridgeRandomNumberGenerator.java>
package bridge;
import camp.nextstep.edu.missionutils.Randoms;
public class BridgeRandomNumberGenerator implements BridgeNumberGenerator {
// ์๋๋ฅผ 0์ผ๋ก ์ง์
private static final int RANDOM_LOWER_INCLUSIVE = 0;
// ์๋ฅผ 1๋ก ์ง์
private static final int RANDOM_UPPER_INCLUSIVE = 1;
// ์(1) or ์๋(0) ์ค ํ๋๋ฅผ ๋ฐํ
@Override
public int generate() {
return Randoms.pickNumberInRange(RANDOM_LOWER_INCLUSIVE, RANDOM_UPPER_INCLUSIVE);
}
public static int generate_num(){
return Randoms.pickNumberInRange(RANDOM_LOWER_INCLUSIVE, RANDOM_UPPER_INCLUSIVE);
}
}
- ์ ์ญ๋ณ์๋ก 0๊ณผ 1๋ก ์ ์๋๋ฅผ ์ข ๋ ์ฝ๊ฒ ๊ตฌ๋ถํ ์ ์๋๋ก ํ์๊ณ ,
generate ๋ฉ์๋๋ฅผ ํตํด 0๊ณผ 1์ค ํ๋๋ฅผ ๊ณจ๋ผ ๋ฐํํ ์ ์๋๋ก ๊ตฌํํ์๋ค.
<InputView.java>
package bridge;
import camp.nextstep.edu.missionutils.Console;
/**
* ์ฌ์ฉ์๋ก๋ถํฐ ์
๋ ฅ์ ๋ฐ๋ ์ญํ ์ ํ๋ค.
*/
public class InputView {
/**
* ๋ค๋ฆฌ์ ๊ธธ์ด๋ฅผ ์
๋ ฅ๋ฐ๋๋ค.
*/
public static int readBridgeSize() {
System.out.println("๋ค๋ฆฌ์ ๊ธธ์ด๋ฅผ ์
๋ ฅํด์ฃผ์ธ์. ");
String input = Console.readLine();
int bridge_length = Integer.parseInt(input);
BridgeMaker.makeBridge(bridge_length);
return bridge_length;
}
/**
* ์ฌ์ฉ์๊ฐ ์ด๋ํ ์นธ์ ์
๋ ฅ๋ฐ๋๋ค.
*/
public static String readMoving() {
System.out.println("์ด๋ํ ์นธ์ ์ ํํด์ฃผ์ธ์. (์: U, ์๋: D)");
String direction = Console.readLine();
return direction;
}
/**
* ์ฌ์ฉ์๊ฐ ๊ฒ์์ ๋ค์ ์๋ํ ์ง ์ข
๋ฃํ ์ง ์ฌ๋ถ๋ฅผ ์
๋ ฅ๋ฐ๋๋ค.
*/
public static String readGameCommand() {
System.out.println("๊ฒ์์ ๋ค์ ์๋ํ ์ง ์ฌ๋ถ๋ฅผ ์
๋ ฅํด์ฃผ์ธ์. (์ฌ์๋: R, ์ข
๋ฃ: Q)");
String game_choice = Console.readLine();
return game_choice;
}
}
- ๋ค๋ฆฌ์ ๊ธธ์ด๋ฅผ ์ ๋ ฅ๋ฐ๊ณ , ์ด๋ํ ์นธ๋ ์ ๋ ฅ๋ฐ์ ๊ฐ๊ฐ ์ ๋ ฅ๋ฐ์ input๊ณผ direction์ผ๋ก
๋ค๋ฅธ ํด๋์ค๋ค์ ํธ์ถํ์ฌ ๊ฐ์ ์ฒ๋ฆฌํ๋ค.
retry()๋ถ๋ถ๋ํ readGameCommand()์ ๊ด๋ จ์ด ์๋๋ฐ, '๋ค์ ์๋ํ ์ง์ ์ฌ๋ถ'๋ฅผ
game_choice์ ๋ด์ readGameCommand()๋ฅผ ์ฐธ์กฐํ๋ ํด๋์ค์ ๊ฐ์ ์ ๋ฌํ ์ ์๋๋ก ํ์๋ค.
<OutputView.java>
package bridge;
/**
* ์ฌ์ฉ์์๊ฒ ๊ฒ์ ์งํ ์ํฉ๊ณผ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํ๋ ์ญํ ์ ํ๋ค.
*/
public class OutputView {
/**
* ํ์ฌ๊น์ง ์ด๋ํ ๋ค๋ฆฌ์ ์ํ๋ฅผ ์ ํด์ง ํ์์ ๋ง์ถฐ ์ถ๋ ฅํ๋ค.
* <p>
* ์ถ๋ ฅ์ ์ํด ํ์ํ ๋ฉ์๋์ ์ธ์(parameter)๋ ์์ ๋กญ๊ฒ ์ถ๊ฐํ๊ฑฐ๋ ๋ณ๊ฒฝํ ์ ์๋ค.
*/
public void printMap() {
String move_print = BridgeGame.map_move(); int count = BridgeGame.endgame_2();
String count_print = " | " + move_print;
for(int i = 0; i <= count; i++){
if(count == 1){
System.out.println("[ " + move_print + " ]"); System.out.println("[ " + move_print + " ]");
}
else if(count >= 1){
System.out.println("[ " + move_print + count_print + " ]");
System.out.println("[ " + move_print + count_print + " | " + move_print + " ]");
}
}
}
/**
* ๊ฒ์์ ์ต์ข
๊ฒฐ๊ณผ๋ฅผ ์ ํด์ง ํ์์ ๋ง์ถฐ ์ถ๋ ฅํ๋ค.
* <p>
* ์ถ๋ ฅ์ ์ํด ํ์ํ ๋ฉ์๋์ ์ธ์(parameter)๋ ์์ ๋กญ๊ฒ ์ถ๊ฐํ๊ฑฐ๋ ๋ณ๊ฒฝํ ์ ์๋ค.
*/
public void printResult() {
String final_result = BridgeGame.endgame_1();
int final_count = BridgeGame.endgame_2();
System.out.println("\n๊ฒ์ ์ฑ๊ณต ์ฌ๋ถ: " + final_result);
System.out.println("์ด ์๋ํ ํ์: " + final_count);
}
}
- ์ต์ข ์ ์ธ ๊ฒฐ๊ณผ์ ์ค๊ฐ ์งํ์ํฉ์ ์ถ๋ ฅํ๋ OutputView๋ ๋งค์ฐ ๊ตฌํ์ด ์ด๋ ค์ ๋ ํด๋์ค ์ค์ ํ๋์๋ค.
move_print๋ผ๋ ๋ณ์๋ก ๋ค๋ฆฌ์ ์ด๋๊ฒฝ๋ก๋ฅผ ๊ทธ๋ ค๋ด์ผํ๋๋ฐ, ์กฐ๊ฑด๋ฌธ์ด ๋ฌด๋ถ๋ณํ๊ฒ ๊ธธ์ด์ง ๊ฒ ๊ฐ์
์ต๋ํ ๊ฐ๋จํ๊ฒ ๊ตฌํ ํ ๋ฆฌํฉํ ๋ง์ ํด๋ณด๊ณ ์ ํ์๋ค.
"์๊ธฐ์น ๋ชปํ ์ค๋ฅ๋ก ์ธํ์ฌ ์คํ์ ์คํจํ์๋ค" ๋ ๋ฌธ๊ตฌ๋ ๊ณผ์ ๋ฅผ ์ํํ๋ฉด์ ๋ง์ด ๊ฒช์ด๋ดค์ง๋ง ์ด๋ฒ 4์ฃผ์ฐจ์์๋
๊ณผ์ ์ํ์ ์ถ์ผ๊น์ง ํด๊ฒฐํ์ง ๋ชปํ์ฑ ๋ง๋ฌด๋ฆฌ๊ฐ ๋์ด๋ฒ๋ ธ๋ค.
๋ฌธ์ ์ธ ๋ถ๋ถ์ ์ถ๋ ฅ์ ๋ด๋นํ๋ OutputView๋ถ๋ถ์ด์๋ ๊ฒ ๊ฐ์๋ฐ ์ฝ๋๋ฅผ ๋ฆฌํฉํ ๋งํ๋ ๊ณผ์ ์์
ํด๋์ค๋ฅผ ๋ฏธ๋ฆฌ ์ธ๋ถํํ์ง ์์ ๊ฒ๋ค์ด ํฐ ์ฅ์ ๋ฌผ์ด ๋์๋ค.๐ญ
๐ฅฒ <๋ง์น๋ฉฐ..> ๐ฅฒ
์ด๋ฒ ํ๋ก์ ํธ๋ฅผ ๊ตฌํํ๋ฉด์ ๋๋์ ์ ๊ฐ ํด๋์ค์ ์ฐธ์กฐ ๋ํ ์ํค๋ฉด ๋งค์ฐ ๋ณต์กํ ์ฝ๋๊ฐ ๋์ด๋ฒ๋ฆฐ๋ค๋ ์ฌ์ค์
์ธ์งํ์๋ค. ํด๋์ค๋ฅผ ๋ฌด์์ ์๊ฒ ๋๋๋ ค ํ๋ค๋ณด๋ ์ด๋ค ๊ธฐ๋ฅ๋ณ๋ก ๋๋์ด์ผํ ์ง ๊ฐ์ด ์กํ์ง ์๋ ๊ฒ๋ ์์๊ณ ,
๊ธฐ๋ฅ์ ๊ตฌํํ์ฌ ๊ทธ ๋ฉ์๋๋ฅผ ๋ค๋ฅธ ํด๋์ค์์ ์ฐธ์กฐํ๋ ๊ณผ์ ์์ ์ธ์๋ฅผ ์ ๋ฌํ๊ณ ๋ฐ๋ ๋ฐฉ์ ๋ํ ํจ๊ณผ์ ์ด์ง ์์๋ค.
๋ง์ง๋ง ์ฃผ์ฐจ๊น์ง ํ๋ฆฌ์ฝ์ค๋ฅผ ์งํํ๋ฉด์ ์ง๊ธ๊น์ง ํด์๋ ํ๋ก์ ํธ์๋ ์ฌ๋ญ ๋ค๋ฅธ ์ฝ๋ ์ค๊ณ ๊ณผ์ ์ฌ์
๋ฐฐ์ธ ์ , ๋ฐฐ์ด ์ ์ด ์ ๋ง ๋ง์๋ค.
๋ชจ๋ ๊ณผ์ ๋ฅผ ์๋ฒฝํ๊ฒ ์ํํด๋ด์ง ๋ชปํ ์ ์ ์์ฝ์ง๋ง, ์ด๋ ค์์ ํด๊ฒฐํด๋๊ฐ๋ ๊ณผ์ , ์ฝ๋๋ฅผ ๋ฆฌํฉํ ๋งํ๋ ๊ณผ์ ์์
์กฐ๊ธ์ ์ฑ์ฅํ์์ ๋๋ ์ ์์๋ค. ๐ข
์ฐ์ํ ํ ํฌ์ฝ์ค ํ๋ฆฌ์ฝ์ค ํ๋ฌ๊ณผ์ ํตํด ๋ง์ ๊ฒ์ ์ป์ด๊ฐ ์ ์์๋ค..๐จ๐ป๐ป๐