1  2 

TCP/IP 텔넷 더미 서버

Date
2009/05/18 06:27
Author
ApPLe
Categories
어쩌..다가 ..
TCP/IP프로토콜을 이용 , 텔넷 더미 서버를 만드는 걸 하게 되었다.
그런데 시작해보니 .. 동기소켓(Sync socket)을 쓴다는것이 저번에 작업했던 와리가리 제어 서버 프로그램과 굉장히 비슷해서 쉽게할 수 있었다..

요구사항은 .. 일반 텔넷 클라이언트 프로그램으로 접속하여 로그인까지 .. 구현하는 것이었는데 .. 재미로 사족을 몇개 달아놓았다 ㅋㅋ

이놈이 서버 프로그램이 돌아가는모습.
서버는 리눅스 환경에서 돌아간다.
10001번 포트를 열고 접속을 받는다.


역시 리눅스 환경에 있는 telnet 클라이언트 프로그램으로 접속한 화면.
꽤나 그럴듯하게 환영메시지 ... 그리고 쉘까지 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
아.. 이 참을수없는 텔넷훼이크의 즐거움 ㅋㅋㅋㅋ


ㅋㅋㅋ 무튼 재미있는 작업이었답 ㅎㅎ
소스코드는 밑에 있답 ㅎㅎ
C언어로 작성했다 ㅎㅎ

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

#define READY_QUEUE 10
#define STRING_MAX 80
#define TRY_MAX 3

#define VALID_ID "drpark"
#define VALID_PW "1111"

enum
{
	FALSE ,
	TRUE
};

typedef struct sockaddr_in SOCKADDR;
typedef int SOCKID;
typedef int BOOL;

void RegistServer ( SOCKADDR *server , int nPort );
void MainLoop ( SOCKID sock_accp );
void SendServerMessage ( SOCKID accp_sock );
int Receive ( SOCKID sock_accp , char buf[] );

int main ( int argc , char **argv )
{
	SOCKADDR server , client;
	SOCKID sock_listen;
	SOCKID sock_accp;
	
	int nAddressLen;

	nAddressLen = sizeof(SOCKADDR);

	if ( argc != 2 )
	{
		printf ( "Invalid parameter : usage : %s [port_number]\n" , argv[0] );
		return 1;
	}

	// Socket listen mode
	sock_listen = socket ( PF_INET , SOCK_STREAM , 0 );

	// server data regist
	RegistServer ( &server , atoi ( argv[1] ) );

	// Binding
	if ( bind ( sock_listen , (struct sockaddr *)&server , sizeof(server)) < 0 )
	{
		printf ( "Bind failed : %d Port already in use.\n" , atoi ( argv[1] ) );
		return 1;
	}

	printf ( "ready for connection..\n" );

	// Listen
	listen ( sock_listen , READY_QUEUE );

	while ( 1 )
	{
		// Accept connection
		sock_accp = accept ( sock_listen , (struct sockaddr *)&client , &nAddressLen );

		printf ( "connected!\n" );

		// Send server Message
		SendServerMessage ( sock_accp );

		// Entry main loop
		MainLoop ( sock_accp );

		// close connection
		close ( sock_accp );

		printf ( "connection closed\n" );
	}
}

void RegistServer ( SOCKADDR *server , int nPort )
{
	bzero ( (char *)server , sizeof(*server) );
	server->sin_family = AF_INET;
	server->sin_addr.s_addr = htonl ( INADDR_ANY );
	server->sin_port = htons ( nPort );
}

void SendServerMessage ( SOCKID accp_sock )
{
	char buf[STRING_MAX];

	strcpy ( buf , "Welcome to dummy telnet server!\ntestID : drpark / testPW : 1111\n\n" );
	write ( accp_sock , buf , strlen(buf) );
}

void MainLoop ( SOCKID sock_accp )
{
	int nByte;
	int i;
	int cnt = 0;

	BOOL bIdExist = FALSE;
	BOOL bPwValid = FALSE;

	char buf[STRING_MAX];

	while ( 1 )
	{
		if ( cnt == TRY_MAX )
		{
			sprintf ( buf , "\n\nlogin failed %d time(s)..\nconnection refused!\n" , TRY_MAX );
			write ( sock_accp , buf , strlen(buf) );
			break;
		}

		strcpy ( buf , "login : " );
		write ( sock_accp , buf , strlen(buf) );
		Receive ( sock_accp , buf );
		
		if ( strcmp ( buf , VALID_ID ) != 0 )
		{
			printf ( "login tried : %s : fail\n" , buf );
			sprintf ( buf , "# login failed : not valid id !\n" );	

			write ( sock_accp , buf , strlen(buf) );
			cnt++;
			continue;
		}

		printf ( "valid id : ask password\n" );

		strcpy ( buf , "password : " );
		write ( sock_accp , buf , strlen(buf) );
		Receive ( sock_accp , buf );

		cnt = 0;

		if ( strcmp ( buf , VALID_PW ) != 0 )
		{
			printf ( "password tried : %s : fail\n" , buf );

			strcpy ( buf , "# login failed : not valid password!\n" );
			write ( sock_accp , buf , strlen(buf) );
			continue;
		}
		
		printf ( "login success.\n" );
		strcpy ( buf , "\n##### LOGIN SUCCESS !!!\nBUT THIS SERVER IS DUMMY.\n\n" );
		write ( sock_accp , buf , strlen(buf) );

		while ( 1 )
		{
			strcpy ( buf , "MINI::$ " );
			write ( sock_accp , buf , strlen(buf) );
			Receive ( sock_accp , buf );

			if ( strcmp ( buf , "shutdown" ) == 0 )
			{
				printf ( "client requests shutdown\n" );
				close ( sock_accp );
				exit ( 0 );
			}
			else if ( strcmp ( buf , "exit" ) == 0 )
			{
				break;
			}
			else if ( strcmp ( buf , "help" ) == 0 )
			{
				strcpy ( buf , "What do you want to me??????\nthis is dummy :)\n" );
				write ( sock_accp , buf , strlen(buf) );
			}
			else
			{
				strcpy ( buf , "MINI shell : syntax error : cannot find command\n" );
				write ( sock_accp , buf , strlen(buf) );
			}
		}

		break;

	}
}

int Receive ( SOCKID sock_accp , char buf[] )
{
	char temp[STRING_MAX];
	int nByte;
	int i;

	nByte = read ( sock_accp , temp , STRING_MAX );

	buf[0] = '\0';

	for ( i = 0 ; i < nByte-2 ; i++ )
	{
		buf[i] = temp[i];
		buf[i+1] = '\0';
	}

	return nByte;
}

ApPLe
2009/05/18 06:27 2009/05/18 06:27
Tag
Trackback
Comments

2009년 금오공대 Software Engineering C설계 3번 Report.

Date
2009/04/12 01:02
Author
ApPLe
Categories
이제 동아리 프로젝트도 막바지...
틈틈히 코드를 문서화하는 도중에 ,, 휴식할 겸 .2009년도 C설계 3번 레포트를 해보았다
( 아안돼 .... 휴식으로 코딩을 하다니 ........ )



총 소요시간은 4시간정도 .
링크드리스트 / 파일입출력 / Ordered Insert 등의 기법이 사용되었답.
그래도 일정관리에 꽤나 효율적인 자료구조가 나온것같아서 기분좋다 ㅋ_ㅋ

음 .. 근데 사실은 노드탐색을 할때 , 가장 최근에 검색된 노드위치를 저장해서 거기서부터 검색해나가면 더욱 퍼포먼스가 좋아지겠다!!
왜냐하면 모든 자료는 Ordered-Insert기법으로 들어가있기때문에 , 시각 ( 시간까지 ) 순으로 정렬되어 있기 때문!!

참고하실분은 받으시라 ㅋ_ㅋ
VS6에서 안돌려보았지만 잘될것같다 ;
gcc에서는 컴파일 / 실행까지 매우 잘된다!!

[다운로드!]

ApPLe
2009/04/12 01:02 2009/04/12 01:02
Tag
Trackback
Comments
물마시니  2009/04/14 00:57  Reply  Delete
이런거 하지마.......................................

=_= 죽는다........................
ApPLe  2009/04/14 06:37  Delete
흐엉 .. =_=;;
넹 ;;
활의노래  2009/04/22 21:33  Reply  Delete
취미로 이런걸 하다니 ㄷㄷ;;
ApPLe  2009/05/10 02:15  Delete
그러게말이여 ,, 흐엉엉..

내가 왜이렇게 되었을까 ㅋㅋㅋ

2009년 금오공대 Software Engineering C설계 2번 Report.

Date
2009/04/02 12:27
Author
ApPLe
Categories
ㅎㅎ 휴학생이지만 레포트는 해보는 중 .. =_=
지겹게 했다고 생각했는데 , 이제는 별로 배울것도 없다고 생각했는데 ,,

막상 해보니 , 은근히 내 코드는 손댈곳이 많다는 것을 깨달았다 =_=;;
더욱더 정진해야겠다..

설화킴!!! 수고했어!! 좋은결과있기를 ...
요새 열심히하는 모습이 보이는 설화킴 ... 보기좋구먼 =_=b
열심히 한만큼 성적이 나올것이야!!

활의노래님도 수고많으셨습니다 =_=b


내가 짜 2009년 C설계 2번째 과제!!  ( 휴학생이 짜는 과제라 ... =_=; )
텍스트이미지 처리 프로그램!!
만족스럽다 =_=bb

C설계 2번과제 내가짠 코드!..



다들 수고하셨습니다
노력하신만큼 좋은 결과 있기를 진심으로 바랍니다!!

ApPLe
2009/04/02 12:27 2009/04/02 12:27
Tag
Trackback
Comments
활의노래  2009/04/02 23:42  Reply  Delete
어유... 저번엔 완전 감사했습니다 ^^;

p.s :
통성명도 했는데 이제 말 놓으셔도 되요.

자 따라해보세요 "영근아~"
ApPLe  2009/04/06 16:49  Delete
감사할것까지야 =_=ㅋㅋ;;

허허허허허허허 ㅋ_ㅋ

말놓는건 술한잔하고 놓도록 하지용 ㅋ_ㅋ

제가 쑥스럼이 많아서 ㅋ_ㅋ

C#을 리눅스에서?! Mono / Gtk# !!

Date
2008/11/28 03:40
Author
ApPLe
Categories
저번에 괴-_-담을 들은 적이 있다.

" C# 개발도 , 리눅스에서 가능혀. "
"풉!"

그때의 나는 한마디 비웃음을 가볍게 흘려주었다. =_=

'뭔소리여 ! .NET프레임워크가 완전 윈도우 종속적인 플랫폼인데 헛소리!'

그러나 ... 나는 븅신이었다 -_-
음... 역시 오픈소스 진영의 힘은 위대했다 ;;
MS에서 개발한 C#을 , 성공적으로 리눅스에서 돌아가도록 포팅한 것이었다;;

그 이름도 거룩한. mono.
리눅스에서 CLI 환경을 구축해서 , .NET 프레임워크의 어플리케이션들이 돌아가게 만든다 =_=.. 멋져부렁!

더 멋진건 .. C#뿐만이 아니라 ASP.NET / VB.NET 까지 돌아간다는것!!

그래서.. 난 당연히 테스트를 해보았다;
컴파일러는 gmcs .
기본적인 C# 콘솔모드 프로그래밍은 이상없이 잘 되었다.

그래서 대-_-망의 GUI 프로그래밍 개시!

using Windows.Form;

이놈을 적어넣고 vi에서 저장을 한후 , 설레이는 마음을 안고 살포시 ,gmcs를 써서 컴파일 하자 마자!

gmcs는 에러메시지로 나를 반겼다 -_-
그런 네임스페이스가 없다나 뭐라나 -_-

인터넷에서 조금 더 알아보았다.
Gtk# 이란 놈이 있었다.

사실 , Tk/Gtk는 전에 Python을 겉-_-핥기식으로 만져볼때 잠깐 만져보았던 놈인데 ,, 크로스플랫폼 GUI 프로그래밍 인터페이스 였던 걸로 기억했었는데..
이놈이 , C#언어에 맞게 '#'이란 타이틀을 달고 리눅스용으로 다시 태어난 것이었다.

Monodoc ( Gtk# / C#용 레퍼런스 ) 를 열심히 읽어보며 , 결국 ,, 난 리눅스 X윈도 상에서 창을 띄우고야 말았다 =_=ㅋㅋ 아우 신기혀;

아차. 팁 한가지!!
gmcs를 써서 Gtk#을 컴파일 할때는 다음과 같이 옵션을 주어 Gtk# 패키지를 지정해 주어야 정상적인 컴파일이 된다!

gmcs source.cs -pkg:gtk-sharp-2.0

음 .. 무튼 결론은 ..
C# MS윈도우즈 프로그래밍이랑 많이 다르지 않았다는게 신기했다.
이벤트 핸들러 등록도 그렇고,, 이벤트 핸들링 메소드에서도 인자도 거의 비슷하게 받았다. 이벤트 핸들링 클래스 이름도 거의 비슷하고..

음.. 근데 많이 다른점은.
MS윈도우즈에서는 , 컨트롤이 폼위에서의 상대좌표에 의해 배치되는 반면 , Gtk#은 , HBox , VBox , Table 이란 놈들로 폼 위에 격자모양으로 딱맞게 배치하는 식이었다.

으흐흐.. 그럼 이쯤에서 적절한 스크린샷.



멘트가 매우 방-_-정맞지만 이정도는 애교로 넘어가주세욤 =_=
무튼.. ㅎㅎ 매우 알기 쉬운 레퍼런스에 ,,
윈도우 C# forms프로그래밍이 가능하다면 ..
금방 익숙해 질수 있다 ; ㅎㅎ
C# 자체가 쉬운 면도 없진 않지만 .;;

사족.



코딩은 vi로 해야지 역시 초간지!!
으흐흐 =_= 전 변태가 된 겁니까 .. ㅜㅜ
콘솔변태 =_=ㅋㅋ




sample program code.

namespace HelloWorld
{
    using System;
    using Gtk;
    using Gdk;

    public class HelloWorld
    {
        public static void Main ( string[] args )
        {
            Application.Init ();
            Gtk.Window win = new Gtk.Window ( "Hello! ApPLe!NET" );

            win.DefaultHeight = 400;
            win.DefaultWidth = 400;

            VBox vbox = new VBox ();
           
            Label lblWelcome = new Label ();
            lblWelcome.Text = "처음으로 만들어보는 mono C# with Gtk#";
            vbox.Add ( lblWelcome );

            Button btn1 = new Button ( "누르면 종료되욤" );
            btn1.Clicked += new EventHandler ( Button1_OnClick );
            vbox.Add ( btn1 );

            Label lblContext = new Label ();
            string szContext = "Gtk로 하니까 참 재미있고 좋군하";
            szContext += "\nC#은 비쥬얼 스튜디오로만 만지다가 이걸로 하니 아주그냥~";
            szContext += "\nhttp://www.applenet.ze.to";
            lblContext.Text = szContext;
            vbox.Add ( lblContext );

            Button btn2 = new Button ( "누르면 글씨가 바뀔꺼예욤" );
            btn2.Clicked += new EventHandler ( Button2_OnClick );
            vbox.Add ( btn2 );

            win.Add ( vbox );

            win.DeleteEvent += new DeleteEventHandler ( Form_OnQueryUnload );
            win.ShowAll ();
            Application.Run ();
        }

        private static void Form_OnQueryUnload ( object sender , DeleteEventArgs e )
        {
            Application.Quit ();
        }

        private static void Button1_OnClick ( object sender , EventArgs e )
        {
            Application.Quit ();
        }

        private static void Button2_OnClick ( object sender , EventArgs e )
        {
            Button btn = (Button)sender;

            btn.Label = "하악하악";
        }
    }
}

ApPLe
2008/11/28 03:40 2008/11/28 03:40
Tag
Trackback
Comments
활의노래  2008/11/30 11:25  Reply  Delete
닷넷 프레임워크가 현재는 윈도용으로만 배포되지만 이것도 일종의 가상머신과 같은 역할을 하기 때문에, 상식적으로도, 이론적으로도 충분히 다른 OS에도 탑재가 가능합니다.

그렇지만 문제는 MS가 그렇게 할 리가 없다는거죠 =ㅅ=;;;
JJD  2008/11/30 18:47  Reply  Delete
역시 오픈소스진영 =_=b
멋지군욤 =_=

몰래 포팅.. 이라는 것이군욤 =_=
지나가다  2008/12/31 21:44  Reply  Delete
모노에서도 WinForms(2.0까지) 지원합니다!
http://www.mono-project.com/WinForms
JJD  2009/01/02 15:40  Delete
흐억

정말이군요 =_=

이럴수가 ㅋㅋ;;

미로찾기 알고리즘.

Date
2008/11/24 18:39
Author
ApPLe
Categories

이번에 만들고 있는 , 미로찾는 프로그램.
이걸 완성한다면 이 알고리즘을 C++이나 , 혹은 C#으로 만드는 게임 등에 적용시킬수 있을 듯하다!

사실 , 어릴 때 아무 생각없이 플레이하던 팩맨도 사실은 이런 꽤 복잡한 알고리즘이 숨겨져있던 거였으니 ..
모르고 있는게 참 속 편하다. (응?)

현재는 단순화 시켜서 표현한다면 다음과 같은 미로


그러니까 , 분기가 단일인 미로는 풀어낼 수 있으나,



다음과 같이 여러 하위 분기가 있는 미로는 풀 수 없다.
하지만 역시 해법도 찾아냈다.

현재는 교차로에서의 진행 거리를 Count하여 그 수만큼 스택에서 Pop시켜 주는 방법을 써 주고 있는데,

앞으로는 , 교차로에서부터 진행거리를 Count하는 변수를 배열로 하여 ,
하위 교차로를 만나면 배열 인덱스를 +1하여 하위 교차로의 정보도 담도록 하면 될 듯하다.

C언어로 작성했으며 ,
gcc , Visual stdio 6.0 에서의 실행을 확인했당.

현재까지의 소스!

#include <stdio.h>
#include <stdlib.h>

#define STACK_MAX 1000
#define FILENAME "mazedata.txt"
#define CLEAR_COMMAND "clear"

#define WALL_CHAR "[]"
#define WAY_CHAR "  "
#define FINDER_CHAR "@@"

#define NO_WAY 999

enum
{
 LEFT ,
  RIGHT ,
  UP ,
  DOWN
};

enum
{
 WAY ,
  WALL ,
  FIND
};

enum
{
 FALSE ,
  TRUE
};

typedef unsigned int DIRECTION;
typedef unsigned int BLOCKDATA;
typedef unsigned int BOOL;

typedef struct _POS
{
 int m_nX;
 int m_nY;
}POS;

typedef struct _SIZE
{
 int m_nHeight;
 int m_nWidth;
}SIZE;

typedef struct _MAZE
{
 BLOCKDATA **m_pData;
 SIZE m_size;
}MAZE;

typedef struct _STACK
{
 POS m_element[STACK_MAX];
 int m_nIndex;
}STACK;

typedef struct _FINDER
{
 POS m_pos;
 DIRECTION m_direction;
}FINDER;

void FindMain ( MAZE *pMaze );

void CreateMaze ( MAZE *pMaze , SIZE size );
void DestructMaze ( MAZE *pMaze );
void LoadMazeDataFromFile ( MAZE *pMaze , char szFileName[] );
void PrintMaze ( MAZE *pMaze , POS finder , STACK *pStack );

void InitStack ( STACK *pStack );
void PushStack ( STACK *pStack , POS data );
void PrintStack ( STACK *pStack );

void MoveFinder ( MAZE *pMaze , FINDER *pFinder );

void GetPossibleDirections ( MAZE *pMaze , FINDER finder , DIRECTION directions[] , int *pDirectionCount );

BLOCKDATA GetBlockByPos ( MAZE *pMaze , POS pos );
DIRECTION GetDirection ( MAZE *pMaze , FINDER finder , STACK *pStack );
DIRECTION GetReverseDirection ( DIRECTION direction );

SIZE GetMazeSizeFromFile ( char szFileName[] );

POS TopStack ( STACK *pStack );
POS PopStack ( STACK *pStack );

BOOL IsStackEmpty ( STACK *pStack );
BOOL IsElementInStack ( STACK *pStack , POS element );

BOOL IsBlocked ( MAZE *pMaze , DIRECTION direction , POS pos );
BOOL IsPosMatch ( POS pos1 , POS pos2 );

int main ( void )
{
 MAZE maze;
 SIZE size;
 
 size = GetMazeSizeFromFile ( FILENAME );
 
 CreateMaze ( &maze , size );
 
 LoadMazeDataFromFile ( &maze , FILENAME );
 
 FindMain ( &maze );
 
 DestructMaze ( &maze );
 
 return 0;
}

void CreateMaze ( MAZE *pMaze , SIZE size )
{
 int i;
 
 pMaze->m_size = size;
 
 pMaze->m_pData = (BLOCKDATA **) malloc ( sizeof(BLOCKDATA *) * (size.m_nHeight+1) );
 
 for ( i = 0 ; i < size.m_nHeight ; i++ )
 {
  pMaze->m_pData[i] = (BLOCKDATA *) malloc ( sizeof(BLOCKDATA) * (size.m_nWidth+1) );
 }
}

void DestructMaze ( MAZE *pMaze )
{
 int i;
 
 for ( i = 0 ; i < pMaze->m_size.m_nHeight ; i++ )
 {
  free ( pMaze->m_pData[i] );
 }
 
 free ( pMaze->m_pData );
}

void LoadMazeDataFromFile ( MAZE *pMaze , char szFileName[] )
{
 FILE *fp;
 char ch;
 
 int nY = 0;
 int nX = 0;
 
 fp = fopen ( szFileName , "r" );
 
 while ( (ch=fgetc(fp)) != EOF )
 {
  if ( ch == '\n' )
  {
   nX = 0;
   nY++;
   continue;
  }
 
  pMaze->m_pData[nY][nX] = (BLOCKDATA)(ch - '0');
 
  nX++;
 }
 
 fclose ( fp );
}

void PrintMaze ( MAZE *pMaze , POS finder , STACK *pStack )
{
 int i , j;
 
 for ( i = 0 ; i < pMaze->m_size.m_nHeight ; i++ )
 {
  for ( j = 0 ; j < pMaze->m_size.m_nWidth ; j++ )
  {
   POS pos;
   pos.m_nX = j;
   pos.m_nY = i;
   
   if ( IsElementInStack ( pStack , pos ) == TRUE )
   {
    printf ( "%s" , ". " );
   }
   else if ( finder.m_nY == i && finder.m_nX == j )
   {
    printf ( "%s" , FINDER_CHAR );
   }
   else
   {
   
    switch ( pMaze->m_pData[i][j] )
    {
    case WAY:
     printf ( "%s" , WAY_CHAR );
     break;
     
    case WALL:
     printf ( "%s" , WALL_CHAR );
     break;
    }
   }
  }
 
  printf ( "\n" );
 }
}

SIZE GetMazeSizeFromFile ( char szFileName[] )
{
 SIZE size;
 FILE *fp;
 char ch;
 
 int nY = 0;
 int nX = 0;
 
 fp = fopen ( szFileName , "r" );
 
 while ( (ch=fgetc(fp)) != EOF )
 {
  if ( ch == '\n' )
  {
   size.m_nWidth = nX;
   nX = 0;
   nY++;
   
   continue;
  }
 
  nX++;
 }
 
 size.m_nHeight = nY;
 
 fclose ( fp );
 
 return size;
}

void InitStack ( STACK *pStack )
{
 pStack->m_nIndex = 0;
}

void PushStack ( STACK *pStack , POS data )
{
 pStack->m_nIndex++;
 pStack->m_element[pStack->m_nIndex] = data;
}

POS TopStack ( STACK *pStack )
{
 return pStack->m_element[pStack->m_nIndex];
}

POS PopStack ( STACK *pStack )
{
 POS res;
 res = pStack->m_element[pStack->m_nIndex];
 pStack->m_nIndex--;
 
 return res;
}

BOOL IsStackEmpty ( STACK *pStack )
{
 if ( pStack->m_nIndex == 0 )
 {
  return TRUE;
 }
 
 return FALSE;
}

void PrintStack ( STACK *pStack )
{
 int i;
 
 printf ( "\n" );
 
 for ( i = 0 ; i <= pStack->m_nIndex ; i++ )
 {
  printf ( "[%d:(X%d Y%d)] " , i+1 , pStack->m_element[i].m_nX , pStack->m_element[i].m_nY );
 }
 
 printf ( "\n" );
}

BLOCKDATA GetBlockByPos ( MAZE *pMaze , POS pos )
{
 return pMaze->m_pData[pos.m_nY][pos.m_nX];
}

BOOL IsBlocked ( MAZE *pMaze , DIRECTION direction , POS pos )
{
 POS temp = pos;
 
 switch ( direction )
 {
 case UP:
  temp.m_nY--;
  break;
 
 case DOWN:
  temp.m_nY++;
  break;
 
 case LEFT:
  temp.m_nX--;
  break;
 
 case RIGHT:
  temp.m_nX++;
  break;
 }
 
 if ( temp.m_nX < 0 || temp.m_nX >= pMaze->m_size.m_nWidth )
 {
  return TRUE;
 }
 
 if ( temp.m_nY < 0 || temp.m_nY >= pMaze->m_size.m_nHeight )
 {
  return TRUE;
 }
 
 if ( GetBlockByPos ( pMaze , temp ) == WALL )
 {
  return TRUE;
 }
 
 return FALSE;
}

BOOL IsPosMatch ( POS pos1 , POS pos2 )
{
 if ( pos1.m_nX == pos2.m_nX &&
  pos1.m_nY == pos2.m_nY )
 {
  return TRUE;
 }
 
 return FALSE;
}

BOOL IsElementInStack ( STACK *pStack , POS element )
{
 int i;
 
 for ( i = 0 ; i <= pStack->m_nIndex ; i++ )
 {
  if ( IsPosMatch ( pStack->m_element[i] , element ) == TRUE )
  {
   return TRUE;
  }
 }
 
 return FALSE;
}

POS GetStartPos ( MAZE *pMaze )
{
 int i , j;
 POS res;
 
 res.m_nX = -1;
 res.m_nY = -1;
 
 for ( i = 0 ; i < pMaze->m_size.m_nHeight ; i++ )
 {
  for ( j = 0 ; j < pMaze->m_size.m_nWidth ; j++ )
  {
   if ( i == 0 && pMaze->m_pData[i][j] == WAY )
   {
    res.m_nY = i;
    res.m_nX = j;
    return res;
   }
  }
 }
 
 return res;
}

POS GetEndPos ( MAZE *pMaze )
{
 int i , j;
 POS res;
 
 for ( i = 0 ; i < pMaze->m_size.m_nWidth ; i++ )
 {
  if ( pMaze->m_pData[pMaze->m_size.m_nHeight-1][i] == WAY )
  {
   res.m_nY = pMaze->m_size.m_nHeight-1;
   res.m_nX = i;
   
   return res;
  }
 }
 
 return res;
}

void FindMain ( MAZE *pMaze )
{
 DIRECTION direction = DOWN;
 POS start;
 POS end;
 FINDER finder;
 STACK pathstack;
 
 int nDistanceFromCrossLoad = 0;
 BOOL bDelived = FALSE;
 
 system ( CLEAR_COMMAND );
 
 InitStack ( &pathstack );
 
 start = GetStartPos ( pMaze );
 end = GetEndPos ( pMaze );
 
 finder.m_pos = start;
 finder.m_direction = DOWN;
 
 while ( IsPosMatch ( finder.m_pos , end ) != TRUE )
 {
  DIRECTION directions[10];
  int nPossibleDirection = 0;
 
  PushStack ( &pathstack , finder.m_pos );
  direction = GetDirection ( pMaze , finder , &pathstack );
 
  GetPossibleDirections ( pMaze , finder , directions , &nPossibleDirection );
 
  if ( nPossibleDirection > 2 )
  {
   bDelived = TRUE;
   nDistanceFromCrossLoad = 0;
  }
 
  if ( bDelived == TRUE )
  {
   nDistanceFromCrossLoad++;
  }
 
  if ( direction == NO_WAY )
  {
   int i;
   
   for ( i = 0 ; i < nDistanceFromCrossLoad ; i++ )
   {
    PopStack ( &pathstack );
   }
   
   direction = directions[0];
   
   bDelived = FALSE;
   nDistanceFromCrossLoad = 0;
  }
 
  finder.m_direction = direction;
 
  MoveFinder ( pMaze , &finder );
 
  PrintMaze ( pMaze , finder.m_pos , &pathstack );
  printf ( "START_POS X%d Y%d\n" , start.m_nX , start.m_nY );
  printf ( "END_POS X%d Y%d\n" , end.m_nX , end.m_nY );
  printf ( "CURRENT_POS X%d Y%d\n" , finder.m_pos.m_nX , finder.m_pos.m_nY );
  printf ( "DISTANCE_FROM_CROSSROAD : %d\n" , nDistanceFromCrossLoad );
 
  //PrintStack ( &pathstack );
 
  //printf ( "TOPSTACK : %d %d\n" , TopStack ( &pathstack ).m_nX , TopStack ( &pathstack ).m_nY );
 
  getchar();
 
  system ( CLEAR_COMMAND );
 }
 
 printf ( "\nFINDING MAZE's PATH COMPLETE!\n" );
}

void MoveFinder ( MAZE *pMaze , FINDER *pFinder )
{
 FINDER temp = *pFinder;
 
 if ( IsBlocked ( pMaze , temp.m_direction , temp.m_pos ) == TRUE )
 {
  return;
 }
 
 switch ( temp.m_direction )
 {
 case DOWN:
  temp.m_pos.m_nY++;
  break;
 
 case UP:
  temp.m_pos.m_nY--;
  break;
 
 case LEFT:
  temp.m_pos.m_nX--;
  break;
 
 case RIGHT:
  temp.m_pos.m_nX++;
  break;
 }
 
 *pFinder = temp;
}

DIRECTION GetDirection ( MAZE *pMaze , FINDER finder , STACK *pStack )
{
 DIRECTION directions[10];
 
 int nPossibleDirection = 0;
 int i;
 
 GetPossibleDirections ( pMaze , finder , directions , &nPossibleDirection );
 
 for ( i = 0 ; i < nPossibleDirection ; i++ )
 {
  POS temp = finder.m_pos;
 
  switch ( directions[i] )
  {
  case LEFT:
   temp.m_nX--;
   break;
   
  case RIGHT:
   temp.m_nX++;
   break;
   
  case UP:
   temp.m_nY--;
   break;
   
  case DOWN:
   temp.m_nY++;
   break;
  }
 
  if ( IsElementInStack ( pStack , temp ) == FALSE )
  {
   return directions[i];
  }
 }
 
 return NO_WAY;
}

void GetPossibleDirections ( MAZE *pMaze , FINDER finder , DIRECTION directions[] , int *pDirectionCount )
{
 FINDER temp = finder;
 
 int i;
 int nIndex = 0;
 
 for ( i = LEFT ; i <= DOWN ; i++ )
 {
  if ( IsBlocked ( pMaze , i , temp.m_pos ) == FALSE )
  {
   directions[nIndex] = i;
   nIndex++;
  }
 }
 
 *pDirectionCount = nIndex;
}

DIRECTION GetReverseDirection ( DIRECTION direction )
{
 DIRECTION res;
 
 switch ( direction )
 {
 case LEFT:
  res = RIGHT;
  break;
 
 case RIGHT:
  res = LEFT;
  break;
 
 case UP:
  res = DOWN;
  break;
 
 case DOWN:
  res = UP;
  break;
 }
 
 return res;
}

 

ApPLe
2008/11/24 18:39 2008/11/24 18:39
Tag
Trackback
Comments

이산수학 레폿 : 퀵소트 ( Quick Sort )

Date
2008/06/09 17:30
Author
ApPLe
Categories

이산수학 레폿으로 했던 퀵 소트!
약간 진보한 버젼으로 , 소트에 걸린시간도 표시해준다 ㅋ_ㅋ
테스트를 해보니 , 자료 80만개를 정렬하는데는 약 4초가 걸렸다;;
으헉 느리다!!! ㅠㅠ 알고리즘 수정 ㄱㄱ싱.


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

#define SIZE 8

typedef struct timeval TIME;

void QuickSort ( int *pData , int nLow , int nHigh , int nPivot );
void Swap ( int *a , int *b );
void Display ( int *pData );

int Separate ( int *pData , int nLow , int nHigh , int nPivot );

double GetProcTime ( TIME start , TIME end );

int main(void)
{
        int i;
        int aData[SIZE];

        double fTime;

        TIME timestart , timeend;

        srand ( time(NULL) );

        for ( i = 0 ; i < SIZE ; i++ )
        {
                aData[i] = rand() % 100;
        }

        printf ( "Original data  : " );
        Display ( aData );
        printf ( "\n" );

        gettimeofday ( &timestart , NULL );

        QuickSort ( aData , 0 , SIZE , 0 );

        gettimeofday ( &timeend , NULL );

        printf ( "\n" );

        printf ( "After Quick-Sort : " );
        Display ( aData );

        fTime = GetProcTime ( timestart , timeend );
        printf ( "Elapsed Time : %lf Sec.\n" , fTime / 1000000 );

        return 0;
}

void QuickSort ( int *pData , int nLow , int nHigh , int nPivot )
{
        printf ( "Sorting.. -> Pivot [%2d] : " , pData[nPivot] );
        Display ( pData );

        if ( nHigh > nLow )
        {
                nPivot = Separate ( pData , nLow , nHigh , nPivot );
                QuickSort ( pData , nLow , nPivot-1 , nPivot );
                QuickSort ( pData , nPivot+1 , nHigh , nPivot );
        }
}

int Separate ( int *pData , int nLow , int nHigh , int nPivot )
{
        int i, j;
        int nItem;

        nItem = pData[nLow];
        j = nLow;

        for( i = nLow + 1 ; i <= nHigh ; i++ )
        {

                if ( pData[i] < nItem )
                {
                        j++;
                        Swap( &pData[i] , &pData[j] );
                }
        }

        nPivot = j;
        Swap ( &pData[nLow] , &pData[nPivot] );

        return nPivot;
}

void Swap ( int *nA , int *nB )
{
        int nTemp;
        nTemp = *nA;
        *nA = *nB;
        *nB = nTemp;
}

void Display ( int *pData )
{
        int i;

        for ( i = 0 ; i <= SIZE ; i++ )
        {
                printf ( "%2d " , pData[i] );
        }

        printf ( "\n" );
}

double GetProcTime ( TIME start , TIME end )
{
        double fRes = 0;

        fRes = ( end.tv_sec/10000 + end.tv_usec ) - ( start.tv_sec/10000 + start.tv_usec );

        return fRes;
}

ApPLe
2008/06/09 17:30 2008/06/09 17:30
Tag
Trackback
Comments

링크드리스트 클래스 , Ver 1.00

Date
2008/05/28 02:15
Author
ApPLe
Categories
자료구조 4차과제를 하기위해서 , 급히 제작하던 링크드리스트 클래스모듈을 완성했다!!
클래스템플릿을 사용하여 , 특정 플랫폼에 구애받지않고 , 어떠한 자료형이던지 링크드리스트로 만들어 줄 수 있다는거 ㅋㅋ

당연히 , C++로 만들었다. STL에 근접할정도의 기능을 넣고 싶었는데,, 음,, 글쎄다 ㅋㅋ

다음 버젼은 Insertion Sort를 사용해서 정렬도 시켜주고 , 내부알고리즘도 개선할 예정!
우아앙 ㅋㅋ 좋구나!

아차,, 그러고보니 주석을 안달았다.. -_-;;
이노메 주석안다는 습관 .. -_-;


1 . linkedclass.h

#ifndef _linkedclass_h
#define _linkedclass_h

#include <iostream>

#define SORT_INDEX_VALUEABLE // Not yet!!

using namespace std;

template <typename T>
class CNode
{
        public:
                T m_node;
                CNode *next;
};

template <typename T>
class CLinkedList
{
        public:
                CLinkedList ();
                virtual ~CLinkedList ();

        public:
                void AddNode ( T node );
                void DeleteNode ( T *pNode );

                T *GetNodePointer ( void );
                T *SearchNode ( T node );

                void SeekNext ( void );
                void SeekLast ( void );
                void SeekFirst ( void );

                bool IsFirstNode ( void );
                bool IsLastNode ( void );

        private:
                CNode<T> *m_pHead;
                CNode<T> *m_pFind;
};

#endif



2 . linkedclass.cpp

#include "linkedclass.h"

template <typename T>
CLinkedList<T>::CLinkedList ()
{
        m_pHead = new CNode<T>;
        m_pHead->next = NULL;

        m_pFind = m_pHead->next;
}

template <typename T>
CLinkedList<T>::~CLinkedList()
{
        CNode<T> *pCurrent;
        CNode<T> *pTempNext;

        pCurrent = m_pHead;

        while ( pCurrent != NULL )
        {
                pTempNext = pCurrent->next;

                delete pCurrent;

                pCurrent = pTempNext;
        }
}

template <typename T>
void CLinkedList<T>::SeekNext ( void )
{
        if ( IsLastNode () == true )
        {
                return;
        }

        m_pFind = m_pFind->next;
}

template <typename T>
void CLinkedList<T>::SeekFirst ( void )
{
        m_pFind = m_pHead->next;
}

template <typename T>
void CLinkedList<T>::SeekLast ( void )
{
        CNode<T> *pFind;

        pFind = m_pHead;

        while ( pFind->next != NULL )
        {
                pFind = pFind->next;
        }

        m_pFind = pFind;
}

template <typename T>
bool CLinkedList<T>::IsLastNode ( void )
{
        CNode<T> *pFind;

        pFind = m_pHead;

        while ( pFind->next != NULL )
        {
                pFind = pFind->next;
        }

        if ( m_pFind == pFind->next )
        {
                return true;
        }

        return false;
}

template <typename T>
bool CLinkedList<T>::IsFirstNode ( void )
{
        if ( m_pFind == m_pHead->next )
        {
                return true;
        }

        return false;
}

template <typename T>
void CLinkedList<T>::AddNode ( T node )
{
        CNode<T> *pFind;
        CNode<T> *pNew;

        pFind = m_pHead;

        pNew = new CNode<T>;
        pNew->m_node = node;

        while ( pFind->next != NULL )
        {
                pFind = pFind->next;
        }

        pFind->next = pNew;
        pNew->next = NULL;
}

template <typename T>
void CLinkedList<T>::DeleteNode ( T *pNode )
{
        CNode<T> *pCurrent;
        CNode<T> *pPrev;

        pPrev = m_pHead;
        pCurrent = m_pHead->next;

        while ( pCurrent != NULL )
        {
                if ( &pCurrent->m_node == pNode )
                {
                        pPrev->next = pCurrent->next;
                        delete pCurrent;
                        return;
                }

                pPrev = pPrev->next;
                pCurrent = pCurrent->next;
        }
}

template <typename T>
T *CLinkedList<T>::GetNodePointer ( void )
{
        T *pRes;

        if ( m_pFind == NULL )
        {
                return NULL;
        }

        pRes = &m_pFind->m_node;

        return pRes;
}

template <typename T>
T *CLinkedList<T>::SearchNode ( T node )
{
        CNode<T> *pFind;

        pFind = m_pHead;

        while ( pFind->next != NULL )
        {
                if ( node == pFind->m_node )
                {
                        return &pFind->m_node;
                }

                pFind = pFind->next;
        }

        return NULL;
}

ApPLe
2008/05/28 02:15 2008/05/28 02:15
Tag
Trackback
Comments

이산수학 레포트 : nXn행렬 역행렬 구하는 프로그램 짜기

Date
2008/05/13 00:21
Author
ApPLe
Categories

우앙, 오늘 하루만에 이산수학 레포트를 끝냈당.
대략 300라인이 쵸큼 넘는 상큼한 레폿이었다, ㅋㅋ

이거하느라 선형대수학 책을 뒤져서 예제를 찾아보고? 제길?;;
디버깅을 위해서 메트랩을 깔고 싶다는 생각도 해보고,, ㅋㅋ

무튼, 완성해서 쵸낸 기쁘다는거!!!!

/*
  이산수학 Report : nXn 행렬 역행렬 구하기
  금오공과대학교 소프트웨어공학전공 20071199 정 진동
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NAME_MAX 80

typedef struct _SQUAREMATRIX
{
        char m_szName[NAME_MAX];
        int m_nSize;

        double **m_pData;
}MATRIX;

void MakeMatrix ( MATRIX *pMatrix , int nSize , char *pName );
void DeleteMatrix ( MATRIX *pMatrix );

void InputMatrix ( MATRIX *pMatrix );
void PrintMatrix ( MATRIX matrix );

double GetDeterminent ( MATRIX matrix );

MATRIX GetTransposeMatrix ( MATRIX matrix );
MATRIX GetAdjointMatrix ( MATRIX matrix );
MATRIX GetMinorMatrix ( MATRIX matrix , int nCol , int nRow );
MATRIX GetConfactorMatrix ( MATRIX matrix );
MATRIX GetInverseMatrix ( MATRIX matrix );

int main (void)
{
        MATRIX matrix;
        MATRIX inverse;

        int nSize;
        char szName[NAME_MAX];
        double fDet;
        double fDetInv;

        printf ( ">> --==== 역행렬 계산 프로그램 ====--\n\n" );
        printf ( "<< 행렬의 크기 : " );
        scanf ( "%d" , &nSize );
        printf ( "<< 행렬의 이름 : " );
        scanf ( "%s" , szName );

        MakeMatrix ( &matrix , nSize , szName );
        MakeMatrix ( &inverse , nSize , szName );

        InputMatrix ( &matrix );
        fDet = GetDeterminent ( matrix );

        inverse = GetInverseMatrix ( matrix );
        fDetInv = GetDeterminent ( inverse );

        PrintMatrix ( matrix );
        printf ( "\n>> 행렬식 : %2.3lf\n" , fDet );

        PrintMatrix ( GetAdjointMatrix ( matrix ) );

        PrintMatrix ( inverse );
        printf ( "\n>> 역행렬의 행렬식 : %2.3lf\n" , fDetInv );

        DeleteMatrix ( &matrix );
        DeleteMatrix ( &inverse );
        return 0;
}

void MakeMatrix ( MATRIX *pMatrix , int nSize , char *pName )
{
        int nCnt;

        pMatrix->m_pData = (double **) malloc ( sizeof(double *) * nSize );

        for ( nCnt = 0 ; nCnt < nSize ; nCnt++ )
        {
                pMatrix->m_pData[nCnt] = (double *) malloc ( sizeof(double) * nSize );
        }

        pMatrix->m_nSize = nSize;
        strcpy ( pMatrix->m_szName , pName );
}

void DeleteMatrix ( MATRIX *pMatrix )
{
        int nCnt;

        for ( nCnt = 0 ; nCnt < pMatrix->m_nSize ; nCnt++ )
        {
                free ( pMatrix->m_pData[nCnt] );
        }

        free ( pMatrix->m_pData );
}

void InputMatrix ( MATRIX *pMatrix )
{
        int i , j;
        double fGet;

        printf ( "\n>> 행렬%s의 성분을 입력하세요!\n" , pMatrix->m_szName );

        for ( i = 0 ; i < pMatrix->m_nSize ; i++ )
        {
                for ( j = 0 ; j < pMatrix->m_nSize ; j++ )
                {
                        fflush ( stdin );
                        printf ( "\n<< %s%d%d : " , pMatrix->m_szName , i+1 , j+1 );
                        scanf ( "%lf" , &fGet );

                        pMatrix->m_pData[i][j] = fGet;
                }
        }

        printf ( "\n>> 입력 종료.\n" );
}

void PrintMatrix ( MATRIX matrix )
{
        int i , j;

        printf ( "\n>> 행렬 %s 를 출력합니다!\n\n" , matrix.m_szName );

        for ( i = 0 ; i < matrix.m_nSize ; i++ )
        {
                printf ( ">> " );
                for ( j = 0 ; j < matrix.m_nSize ; j++ )
                {
                        printf ( "%2.1lf " , matrix.m_pData[i][j] );
                }
                printf ( "\n" );
        }
}

double GetDeterminent ( MATRIX matrix )
{
        int i;
        double fDet = 0;
        int nSign = 1;

        if ( matrix.m_nSize == 2 )
        {
                fDet = matrix.m_pData[0][0] * matrix.m_pData[1][1] -
                        matrix.m_pData[1][0] * matrix.m_pData[0][1];
                return fDet;
        }

        fDet = 0;

        for ( i = 0 ; i < matrix.m_nSize ; i++ )
        {
                MATRIX minor;
                MakeMatrix ( &minor , matrix.m_nSize , matrix.m_szName );

                minor = GetMinorMatrix ( matrix , 0 , i );

                fDet = fDet + nSign * matrix.m_pData[i][0] * GetDeterminent( minor ); //
                nSign = nSign * -1;

                DeleteMatrix ( &minor );
        }

        return fDet;
}

MATRIX GetTransposeMatrix ( MATRIX matrix )
{
        MATRIX res;
        int i , j ;
        char szName[NAME_MAX];

        strcpy ( szName , "Transpose of " );
        strcat ( szName , matrix.m_szName );

        MakeMatrix ( &res , matrix.m_nSize , szName );

        for ( i = 0 ; i < matrix.m_nSize ; i++ )
        {
                for ( j = 0 ; j < matrix.m_nSize ; j++ )
                {
                        res.m_pData[i][j] = matrix.m_pData[j][i];
                }
        }

        return res;
}

MATRIX GetMinorMatrix ( MATRIX matrix , int nCol , int nRow )
{
        MATRIX res;
        int nCnt;

        int i , j;
        int nRowIndex = 0;
        int nColIndex = 0;
        char szName[NAME_MAX];

        strcpy ( szName , "Minor-matrix of " );
        strcat ( szName , matrix.m_szName  );

        MakeMatrix ( &res , matrix.m_nSize - 1 , szName );

        for ( i = 0 ; i < matrix.m_nSize ; i++ )
        {
                for ( j = 0 ; j < matrix.m_nSize ; j++ )
                {
                        if ( i != nRow && j != nCol )
                        {
                                res.m_pData[nRowIndex][nColIndex] = matrix.m_pData[i][j];

                                nColIndex++;
                        }
                }

                if ( i != nRow && j != nCol )
                {
                        nColIndex = 0;
                        nRowIndex++;
                }
        }

        return res;
}

MATRIX GetConfactorMatrix ( MATRIX matrix )
{
        MATRIX res;
        char szName[NAME_MAX];
        int i , j;

        strcpy ( szName , "Confactor Matrix of " );
        strcat ( szName , matrix.m_szName );

        MakeMatrix ( &res , matrix.m_nSize , szName );

        for ( i = 0 ; i < matrix.m_nSize ; i++ )
        {
                for ( j = 0 ; j < matrix.m_nSize ; j++ )
                {
                        res.m_pData[j][i] = GetDeterminent ( GetMinorMatrix ( matrix , i , j ) );
                }
        }

        return res;
}

MATRIX GetAdjointMatrix ( MATRIX matrix )
{
        MATRIX res;
        MATRIX confactor;
        MATRIX transposed;
        char szName[NAME_MAX];
        int i , j;
        int nSign = 1;

        strcpy ( szName , "Adjoint Matrix of " );
        strcat ( szName , matrix.m_szName );

        MakeMatrix ( &res , matrix.m_nSize , szName );
        MakeMatrix ( &confactor , matrix.m_nSize , szName );
        MakeMatrix ( &transposed , matrix.m_nSize , szName );

        confactor = GetConfactorMatrix ( matrix );
        transposed = GetTransposeMatrix ( confactor );

        for ( i = 0 ; i < matrix.m_nSize ; i++ )
        {
                for ( j = 0 ; j < matrix.m_nSize ; j++ )
                {
                        res.m_pData[i][j] = nSign *transposed.m_pData[i][j];

                        nSign = nSign * -1;
                }
        }

        DeleteMatrix ( &confactor );
        DeleteMatrix ( &transposed );

        return res;
}

MATRIX GetInverseMatrix ( MATRIX matrix )
{
        MATRIX res;
        MATRIX temp;
        char szName[NAME_MAX];
        double fDet;

        int i , j;

        fDet = GetDeterminent ( matrix );

        strcpy ( szName , "Inverse Matrix of " );
        strcat ( szName , matrix.m_szName );

        MakeMatrix ( &temp , matrix.m_nSize , matrix.m_szName );
        MakeMatrix ( &res , matrix.m_nSize , szName );

        temp = GetAdjointMatrix ( matrix );

        for ( i = 0 ; i < matrix.m_nSize ; i++ )
        {
                for ( j = 0 ; j < matrix.m_nSize ; j++ )
                {
                        res.m_pData[i][j] = (double)((double)1/fDet) * temp.m_pData[i][j];
                }
        }

        DeleteMatrix ( &temp );

        return res;
}

ApPLe
2008/05/13 00:21 2008/05/13 00:21
Tag
Trackback
Comments

C설계 두번째 과제 : 행맨 ( hang man )

Date
2008/04/24 05:26
Author
ApPLe
Categories

드디어, 이혀놔교수님의 미칠듯한 두 번째 과제, 행맨을 완성했다!
제길,, 2주간의 인고의 세월이 빚어낸 근성의 결과물이다..

후후훗,, 대략 보고서로 뽑으면 40장이 나오는 방대한 코드들? 근성이 아닐 수 없다?

총 라인수 1200라인 , 개발기간 2주일의 피눈물나는 근성의 프로그램?
하지만 많은 것을 공부할 수 있었다?

메모리재할당 함수인 realloc() , 그리고 , 파일을 읽어들일때 효율적인 알고리즘 , GCC에서의 여러 파일 컴파일 방법 , GCC에서 log10() , log() 함수를 비롯한 함수를 쓰기위한 컴파일 옵션 , Vi 에디터의 멋진 사용법 등....

이녀석을 위해서 대략 2주간을 미칠듯한 708에서 밤을 샜고? 새벽 5시인 지금도 사실 708이다?
기분은 솔직히 쩐다? 첫번째 과제인 볼링점수계산은 실패했기 때문에 만회한 느낌이랄까?

오랜만에 뭔가를 이루어낸 느낌이라서 좋구나?
그리고..... 또 한가지..

난 .. 비쥬얼스튜디오보다 왠지 Vi + gcc + gdb가 더 애착이 가게 되어버렸지? ㄲㄲㄲ?
이젠 검정색 바탕화면을 보지 않으면 코딩이 안될정도? ㄲㄲ?

무튼,, 다운받아보아라?
피눈물의 결정체?

다운받아라? 우와아아앙?

ApPLe
2008/04/24 05:26 2008/04/24 05:26
Tag
Trackback
Comments
뇽뇽이  2008/04/25 00:34  Reply  Delete
구글에서 c언어 행맨 치니까 니 블로그가 1등-_-
jessica rabbit adult  2008/05/23 04:39  Reply  Delete
관심을 끌. 너가 좋을 동일할 지점을.
걸출한 디자인! 좋은 디자인.
glass fishbowl  2008/05/24 00:13  Reply  Delete
우수한 디자인!!
first time anal movies  2008/05/24 00:19  Reply  Delete
저에서 유사한 역사는 이었다.
hmg coa reductase inhibitor  2008/05/24 00:22  Reply  Delete
이 위치는 아니라 유익한뿐 재미있는다!
peliculas sexo  2008/05/24 00:28  Reply  Delete
친구는 너의 현재 위치의 팬이 되었다!

C로 짠 .. 치한 *-_-* 게임

Date
2007/11/17 03:58
Author
ApPLe
Categories

아니 뭐..
솔직히 막상 이름붙이려니 적당한게 없어서..

굳이 붙이자면 '추격자 (Chaser)' 게임 쯤 될까요..

콘솔모드긴 해도 A , D , W ,S 키를 방향키처렴 움직여서 여인을 움직여서 한마리 늑대처럼 따라오는 남자에게서 계속 도망쳐야 하는 게임이지염 -_-

아흙. rand() 함수를 써서 여자와 남자의 위치를 조건으로 난수를 발생시켜 쫓아오는것처럼 보이게 만들었어염.. 나름 인공지능 -_- 일까요.... 아흙

맵 데이터 파일도 있으니, 아래 소스만으로는 실행이 안되염~
그러므로 밑의 소스는 참고만 하시고, 소스를 다운로드 받으시길 바래염~

맵 데이터와 소스는 같은 폴더에 넣어주시고 컴파일 ㄳ

[소스 다운로드]

심심풀이로 만든, 여자를 쫄쫄 따라다니는 남자를 피해야하는 -_- 게임입니다.
조작은 서X어택처럼 A D W S 키로 해주시면 됩니다.

여기 있는 소스만으로는 실행이 안됩니다.
첨부파일 내의 mazedata.dat 파일을 maze.c가 위치한 폴더내에 넣어주시고 컴파일 해주세요.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <windows.h>

#define dfMaze_height 10
#define dfMaze_width 20

#define TRUE 1
#define FALSE 0

typedef struct stCharacter{
int pos_x;
int pos_y;
}tdChar;

typedef struct stYpos{
int nXpos[dfMaze_width];
}tdYpos;

void read_mazedata(tdYpos *pPosy);
void move_character(tdChar *tdpTemp, int nLeft, int nRight, int nUp, int nDown,char sCharacter[2]);
void display_map(tdYpos *pTempstr);
void display_setcursor(int nPosx, int nPosy);
int check_moveable(tdChar *tdpTemp, tdYpos *pPos,int nLeft, int nRight, int nUp, int nDown);
void move_enemy(tdChar *pEnemy, tdChar *pPlayer, tdYpos *pYpos);
void display_intro(void);

int main(void){
tdYpos tdvPosy[dfMaze_height];
tdChar tdvPlayer;
tdChar tdvEnemy;
int nCount=0;
char chGet;

srand(time(NULL));

tdvPlayer.pos_x=1;
tdvPlayer.pos_y=1;
tdvEnemy.pos_x=18;
tdvEnemy.pos_y=8;

read_mazedata(tdvPosy);
display_map(tdvPosy);

move_character(&tdvPlayer,FALSE,FALSE,FALSE,FALSE,"♀");
move_character(&tdvEnemy,FALSE,FALSE,FALSE,FALSE,"♂");

while(1){
if(kbhit()){
  chGet=getch();
  if(chGet=='a'){
   if(check_moveable(&tdvPlayer,tdvPosy,TRUE,FALSE,FALSE,FALSE)==TRUE){
    move_character(&tdvPlayer,TRUE,FALSE,FALSE,FALSE,"♀");
   }
  }
  else if(chGet=='d'){
   if(check_moveable(&tdvPlayer,tdvPosy,FALSE,TRUE,FALSE,FALSE)==TRUE){
    move_character(&tdvPlayer,FALSE,TRUE,FALSE,FALSE,"♀");
   }
  }
  else if(chGet=='w'){
   if(check_moveable(&tdvPlayer,tdvPosy,FALSE,FALSE,TRUE,FALSE)==TRUE){
    move_character(&tdvPlayer,FALSE,FALSE,TRUE,FALSE,"♀");
   }
  }
  else if(chGet=='s'){
   if(check_moveable(&tdvPlayer,tdvPosy,FALSE,FALSE,FALSE,TRUE)==TRUE){
    move_character(&tdvPlayer,FALSE,FALSE,FALSE,TRUE,"♀");
   }
  }
}

nCount++;

if(nCount==5000){
  move_enemy(&tdvEnemy,&tdvPlayer,tdvPosy);
  if(tdvPlayer.pos_x==tdvEnemy.pos_x&&tdvPlayer.pos_y==tdvEnemy.pos_y){
   display_setcursor(30,18);
   printf("G A M E O V E R\n");
   getch();
   break;
  }
  nCount=0;
}
}
return 0;
}

void read_mazedata(tdYpos *pPosy){
FILE *fp;
char saTemp_maze[dfMaze_height+1][dfMaze_width+1];
int nLinecount=0;
int nCount_i,nCount_j;

fp=fopen("mazedata.dat","r");

while(!feof(fp)){
fscanf(fp,"%s",saTemp_maze[nLinecount]);
nLinecount++;
}

for(nCount_i=0;nCount_i<=dfMaze_height-1;nCount_i++){
for(nCount_j=0;nCount_j<=dfMaze_width-1;nCount_j++){
  if(saTemp_maze[nCount_i][nCount_j]=='0'){
   pPosy[nCount_i].nXpos[nCount_j]=0;
  }
  else if(saTemp_maze[nCount_i][nCount_j]=='1'){
   pPosy[nCount_i].nXpos[nCount_j]=1;
  }
}
}

fclose(fp);
}

void move_character(tdChar *tdpTemp, int nLeft, int nRight, int nUp, int nDown,char sCharacter[2]){
display_setcursor((tdpTemp->pos_x)*2,tdpTemp->pos_y);
printf("  ");

if(nLeft==TRUE){
tdpTemp->pos_x--;
}
else if(nRight==TRUE){
tdpTemp->pos_x++;
}
else if(nUp==TRUE){
tdpTemp->pos_y--;
}
else if(nDown==TRUE){
tdpTemp->pos_y++;
}

display_setcursor((tdpTemp->pos_x)*2,tdpTemp->pos_y);
printf("%s",sCharacter);
}

void display_setcursor(int nPosx, int nPosy){
COORD coPos={nPosx,nPosy};
  SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coPos);
}

void display_map(tdYpos *pTempstr){
int nCount_i;
int nCount_j;

for(nCount_i=0;nCount_i<=dfMaze_height-1;nCount_i++){
for(nCount_j=0;nCount_j<=dfMaze_width-1;nCount_j++){
  display_setcursor(nCount_j*2,nCount_i);
  if(pTempstr[nCount_i].nXpos[nCount_j]==1){
   printf("■");
  }
  else if(pTempstr[nCount_i].nXpos[nCount_j]==0){
   printf("  ");
  }
}
}
}

int check_moveable(tdChar *pChar_temp, tdYpos *pPos, int nLeft, int nRight, int nUp, int nDown){
if(nLeft==TRUE){
if(pChar_temp->pos_x!=0){
  if(pPos[pChar_temp->pos_y].nXpos[pChar_temp->pos_x-1]==1){
   return FALSE;
  }
  else{
   return TRUE;
  }
}
return FALSE;
}
if(nRight==TRUE){
if(pChar_temp->pos_x!=dfMaze_width-1){
  if(pPos[pChar_temp->pos_y].nXpos[pChar_temp->pos_x+1]==1){
   return FALSE;
  }
  else{
   return TRUE;
  }
}
return FALSE;
}
if(nUp==TRUE){
if(pChar_temp->pos_y!=0){
  if(pPos[pChar_temp->pos_y-1].nXpos[pChar_temp->pos_x]==1){
   return FALSE;
  }
  else{
   return TRUE;
  }
}
return FALSE;
}
if(nDown==TRUE){
if(pChar_temp->pos_x!=dfMaze_height-1){
  if(pPos[pChar_temp->pos_y+1].nXpos[pChar_temp->pos_x]==1){
   return FALSE;
  }
  else{
   return TRUE;
  }
}
return FALSE;
}
return 0;
}

void move_enemy(tdChar *pEnemy, tdChar *pPlayer, tdYpos *pYpos){
int nRandom;
int aMove[4];

// LEFT 0 , RIGHT 1 , UP 2, DOWN 3
nRandom=rand()%3+1;

if(pPlayer->pos_x<pEnemy->pos_x){
aMove[0]=0;
aMove[1]=0;
aMove[2]=2;
aMove[3]=3;
}
else{
aMove[0]=1;
aMove[1]=1;
aMove[2]=2;
aMove[3]=3;
}

if(pPlayer->pos_y<pEnemy->pos_y){
aMove[0]=2;
aMove[1]=2;
aMove[2]=0;
aMove[3]=1;
}
else{
aMove[0]=3;
aMove[1]=3;
aMove[2]=0;
aMove[3]=1;
}

switch(aMove[nRandom]){
case 0:
if(check_moveable(pEnemy,pYpos,TRUE,FALSE,FALSE,FALSE)==TRUE){
  move_character(pEnemy,TRUE,FALSE,FALSE,FALSE,"♂");
}
break;
case 1:
if(check_moveable(pEnemy,pYpos,FALSE,TRUE,FALSE,FALSE)==TRUE){
  move_character(pEnemy,FALSE,TRUE,FALSE,FALSE,"♂");
}
break;
case 2:
if(check_moveable(pEnemy,pYpos,FALSE,FALSE,TRUE,FALSE)==TRUE){
  move_character(pEnemy,FALSE,FALSE,TRUE,FALSE,"♂");
}
break;
case 3:
if(check_moveable(pEnemy,pYpos,FALSE,FALSE,FALSE,TRUE)==TRUE){
  move_character(pEnemy,FALSE,FALSE,FALSE,TRUE,"♂");
}
break;
}
}

ApPLe
2007/11/17 03:58 2007/11/17 03:58
Tag
Trackback
Comments
1  2