[자료구조] 원형 이중연결리스트 가위바위보 만들기

학교 자료구조 스터디의 첫번째 과제가 나왔다.
바로 원형 이중연결리스트를 활용하여서 가위바위보 게임을 만드는 것이다!!!

일주일동안 되게~! 많이 고민하다가(사실 귀찮아서 천천히했다) 과제 마감 하루전날 커피 마시면서 새벽3시까지 해서 마무리했다.

그러면 바로 코드를 보여주겠다.

RSP.h

//
//  RSF.h
//  StructData_assignment_3
//

#ifndef RSF_h
#define RSF_h

#define TRUE 1
#define FALSE 0

typedef int Data;

typedef struct node // 노드 구조체
{
    Data win; // 플레이어 이긴 횟수 저장
    Data lose; // 플레이아 진 횟수 저장
    struct node * right; // next
    struct node * left; // prev
    Data name; // 노드 이름
}Node;

typedef struct _dbLinkedList{ // 이중연결려스트
    Node * cumputer_ptr; // 컴퓨터 
    Node * head; // 머리(맨 앞 데이터 표시)
    Node * cur; // 조회 목적
    Data numOfNode; // 총 노드의 겟수
}DBLinkedList;

typedef DBLinkedList List;

void ListInit(List * plist); // 초기화

void insertEnd(List*plist); // 끝에 노드 추가

void LWinInsert(List * plist,Node * computer_ptr); // 이겼을 시 양 옆에 win.lose 을 가진 데이터 삽입
int LCount(List * plist); // 모든 노드의 개수 반환

// 노드 출력
void printNode(List * plist);

// 플레이어 짐(캄퓨터 승)
void playerLose(List * plist);

// 플레이어 이김(컴퓨터 짐 )
void playerWin(List * plist);

// 노드삭제
void LoseRemove(List * plist);


#endif /* RSF_h */

RSP.c

//
//  RSF.c
//  StructData_assignment_3
//
#include <stdio.h>
#include <stdlib.h>
#include "RSF.h"

void ListInit(List * plist) // 초기화 함수
{
    plist->cumputer_ptr = plist->head; // 컴퓨터 머리가리키기 이게맞나..?
    plist->head = NULL;
    plist->numOfNode = 0;
//    plist->cumputer_ptr = plist->head;
}

// 양방향 삽입
// 컴퓨터 노드 받기
void LWinInsert(List * plist,Node * computer_ptr)
{
    
    //왼쪽 노드 생성
    Node * newNodeLeft = (Node*)malloc(sizeof(Node));
    newNodeLeft->win=0;
    newNodeLeft->lose=0;
    (plist->numOfNode)++;
    newNodeLeft->name = plist->numOfNode; // 이름 설정
    
    // 오른쪽 노드 생성
    Node * newNodeRight = (Node*)malloc(sizeof(Node));
    newNodeRight->win=0;
    newNodeRight->lose=0;
    (plist->numOfNode)++;
    newNodeRight->name = plist->numOfNode;

    
    // 연결해주기
    // 오른쪽
    // computer_ptr 다음 노드와 오른쪽 삽입된 노드간의 연결
    newNodeRight->right = computer_ptr->right;
    computer_ptr->right->left = newNodeRight;
    
    //computer_ptr 노드와 오른쪽 삽입 새 노드 연결
    computer_ptr->right = newNodeRight;
    newNodeRight->left = computer_ptr;
    
    
    //왼쪽
    //computer_ptr 이전 노드와 왼쪽 삽입된 노드간의 연결
    newNodeLeft->left = computer_ptr->left;
    computer_ptr->left->right = newNodeLeft;
    
    //computer_ptr 노드와 왼쪽 삽입 새 노드 연결
    computer_ptr->left = newNodeLeft;
    newNodeLeft->right = computer_ptr;
}

void playerWin(List * plist) //플레이어 승리시
{
    plist->cumputer_ptr->win++; // 승 하나 올리기
    if((plist->cumputer_ptr->win) >= 2) // 2이상 일때
    {
        //노드 양방향 삽입
        plist->cumputer_ptr->win = 0; // 승리 0초기화
        LWinInsert(plist,plist->cumputer_ptr); // 양쪽 새노드 삽입
    }
    plist->cumputer_ptr = plist->cumputer_ptr->left; // 왼쪽으로 이동
}

void playerLose(List * plist) // 플레이어 패배시
{
    plist->cumputer_ptr->lose =plist->cumputer_ptr->lose + 1; // 패배 하나 올리기
    if((plist->cumputer_ptr->lose)>=2) // 패배 2이상
    {
        LoseRemove(plist);
    }
    plist->cumputer_ptr = plist->cumputer_ptr->right; // 오른쪽 이동
}


// 노드제거
 void LoseRemove(List * plist)
{
     Node * rpos = plist->cumputer_ptr;
     
     plist->cumputer_ptr->left->right = plist->cumputer_ptr->right;
     plist->cumputer_ptr->right->left = plist->cumputer_ptr->left;
     
     plist->cumputer_ptr = plist->cumputer_ptr->left; // 컴퓨터 왼쪽으로 이동
     free(rpos);
     (plist->numOfNode)--;
 }


void insertEnd(List*plist) // 노드 뒤로 이어가기
{
    if(plist->head== NULL) // 리스트가 비어있다면
    {
        Node * newNode = (Node*)malloc(sizeof(Node));
        newNode->win=0;
        newNode->lose=0;
        newNode->right = newNode->left = newNode;//자기자신을 가리킴 -> 원형
        plist->head = newNode;
        plist->cumputer_ptr = plist->head;
        return;
    }
    
    //노드가 비어있지 않다면
    Node * last = plist->head->left; // 마지막 노드 찾기
    Node * newNode = (Node*)malloc(sizeof(Node));
    newNode->win = 0;
    newNode->lose = 0; // 초기화 진행
    
    newNode->right = plist->head;
    plist->head->left = newNode;
    newNode->left = last;
    last->right = newNode;
    
    (plist->numOfNode)++; // 노드 숫자 증가
    newNode->name = plist->numOfNode; // 노드 번호 할당
}

// 총노드갯수
int LCount(List * plist)
{
    return plist->numOfNode+1;
}

// 노드 출력
void printNode(List * plist){
    int numNodes = plist->numOfNode+1;
    if(plist->head==NULL)
    {
        return ;
        
    }
    plist->cur = plist->head; // cur 이 첫번째 노드 가리킴
    if(LCount(plist)==0)
        printf("HEAD*");
    else{
        printf("HEAD");
    // 제일 처음 출력 => HEAD*
    // 컴퓨터 노드 위치 까지 계산 후 그 위치에 * 찍기...
    for(int j=0 ;j<numNodes;j++)
    {
        if(plist->cur == plist->cumputer_ptr)
        {
            printf("->NODE%d*(WIN:%D LOSE:%d)<-",plist->cur->name+1,plist->cur->win,plist->cur->lose);
        }
        else
        {
        printf("->NODE%d(WIN:%D LOSE:%d)<-",plist->cur->name+1,plist->cur->win,plist->cur->lose);
        }
        plist->cur = plist->cur->right;
    }
    }
}

Main.c

//
//  main.c
//  StructData_assignment_3
//
//

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "RSF.h"


int main(void)
{
    srand((unsigned)time(NULL));
    List list;

    int i;
    int numNode; // 초기 노드의 갯수
    int userNum=0; //가위바위보
    int computerNum=0; // 컴퓨터의 선택
    //int numberOfNode=0; // 노드번호
    printf("가위바위보 게임에 오신것을 환영합니다 \n");
    printf("입력하신 수 만큼의 노드를 가진 원형 이중연결리스트가 생성됩니다.\n");
    printf("*는 컴퓨터의 위치입니다.\n");
    printf("플레이어 승리시 컴퓨터는 왼쪽 노드로 이동합니다.\n");
    printf("플레이어 패배시 컴퓨터는 오른쪽 노드로 이동합니다\n");
    printf("\n초기 노드 개수를 입력해주세요  : ");
    scanf("%d",&numNode);
    
    ListInit(&list); // 초기화
    
    // numNode 만큼 노드 만들기
    for(i=0;i<numNode;i++)
    {
        insertEnd(&list); // 노드 추가
    }
    
    printf("총 노드 갯수 : %d\n",LCount(&list));
    // node상태 화면 출력
    printf("\n");
    printNode(&list);
    printf("\n");
    //가위바위보

    while(userNum!=4)
    {
        if(LCount(&list)==0)
        {
            printf("\n더 이상의 노드가 존재하지 않습니다\n");
            break;
        }
        while(1) // 에러 처리
        {
            printf("\n선택하세요.(1.가위,2.바위,3.보,4.끝내기) : ");
            scanf("%d",&userNum);
            if(userNum<=4 && userNum>0)
                break;
            else
                printf("1~4사이의 숫자를 입력해주세요.\n");
        }
        
        // computerNum 구하기
        computerNum = rand()%3+1;
    
        // 가위바위보 하기
        if((userNum==1&& computerNum ==3)||(userNum==2&& computerNum ==1)||(userNum==3&& computerNum ==2)) // 플레이어 승
        {
            printf("컴퓨터가 패배했습니다.왼쪽 노드로 이동합니다.\n");
            playerWin(&list);
            
        }
        else if(userNum ==  computerNum) // 비김
        {
            printf("비겼습니다.\n");
            continue;
        }
        else if((userNum == 1 && computerNum ==  2)||(userNum == 2 && computerNum == 3)||(userNum == 3 && computerNum == 1)) // 플레이어 짐
        {
            printf("컴퓨터가 승리했습니다. 오른쪽 노드로 이동합니다. \n");
            playerLose(&list);
        }
        
        // 총 노드 갯수 출력 : LCount 함수
        printf("총 노드 갯수 : %d\n",LCount(&list));
        // node상태 화면 출력
        printNode(&list);
        printf("\n");
    }
    
    printf("\n 프로그램을 종료합니다. \n");

    return 0;
        }    

이렇게하면 매우 잘돌아간다!!!!!


그랬는데..
스터디 당일날 코드리뷰를 하면서
돌려봤는데...
안돌ㅇ간다...
왜 이렇지
갑자기 왜??
내가 뭘 잘못했는데!!!!

왜 이런거냐구!!!!
흐규 후긓구그ㅜ


그리고 구조체 맴버로 쓰지 않고 노드이름을 설정하는 방법과
노드1만 LOSE가 2 이상일때 사라지지않는 버그가 있다... ㅠㅠ

좋은 웹페이지 즐겨찾기