Academic Project2008. 12. 16. 19:51
프로그래밍 언어2 기말 Open Book Test로 시작된 두더지 잡기 게임...
MFC를 이용하여 일주일안에 작성해오는 것이 이번 과제다.

먼저 문제에 대한 설명을 하자면
어렸을 때 누구나 한 번쯤 해보았을 법한 두더지 잡기 게임이다.
이런 거......

교수님께서 설명 해 주신 바로는,
게임이 시작하면 화면에 Random으로 두더지가 나타났다가 일정한 시간이 지나면 사라진다.
두더지를 마우스커서로 클릭하면 점수가 올라간다. 두더지가 나타났다 사라지는 시간은 점점 짧아진다.
정해진 시간(설정 가능!)이 지나면 점수를 표시하고 게임은 종료된다.

요구사항은,
MFC를 이용한 SDI프로그램이어야하며,
두더지는 나타날 때의 모습과 클릭했을 때의 모습이 달라야 한다.
경과 시간과 점수를 상태바에 표시하여야 한다.
1,2,3등의 등수와 점수가 저장되어야 한다.

이런 프로그램을 작성하기 전에는 먼저 로직을 구상하는 것이 먼저 일 것이다.

시험 문제로 게임에 필요한 변수를 적을 때는 먼저 Document 배열에 두더지를 표시하고 View에서 배열에 나와있는 두더지의 3가지 상태(없음, 나옴, 잡힘)를 보고 화면에 그릴 생각이었다.
하지만 생각해보니 두더지는 한 타이밍에 하나씩만 나오는 것이 좋을 것으로 보고
배열은 제외.
단순히 CPoint형으로 두더지가 나타난 위치를 지정하고
int형으로 하여 두더지상태가 어떤지 3가지 상태를 저장할 수 있도록 하기로 했다.

일단 뷰는 기존 오델로와 같은 방식으로 틀을 그리고 나타난 두더지는 흰 동그라미,
잡힌 두더지는 검은 동그라미로 나오도록 하기로 했다.

시간제한이 관건이므로 OnTimer(시험때는 이 함수가 떠오르지않아 시간 이벤트라고 적었다ㅜㅠ)를 사용
타이머 발생시 마다 두더지를 만들고 화면을 다시 그리도록 하고,

WM_LBOTTONDOWN메시지(마우스 왼쪽 버튼 클릭)가 발생하면 그 위치를 확인하여
두더지가 나타난 지점과 일치하면 상태를 '잡힘'으로 하고 점수를 증가 시킨다.

이렇게만 하면 메시지는 3가지면 된다.

구상은 간단했다.

하지만, 실제 구현이 문제....
다음 글에 이렇게 구현된 두더지 잡기 게임을 공개하겠다.
Posted by Hugh.Kim
Academic Project2008. 12. 16. 18:57


이미 완성되어 제출일만을 기다리고 있는 방명록이지만,
2학기부터 뭔가 성취감있는 프로젝트(과제들)가 많아
이참에 시작할 때로 거슬러 올라가 블로깅을 해보려고 한다.

첫 블로깅이라 어색한 점이 많지만...
머... 하다보면 나아지지 않을까 싶은데.....ㅋㅋ

일단 교재부터 한번 개시 해 볼까???


PHP프로그래밍 입문...
그렇다...
일단 hurryon교수님(성균관대에 계신 교수님인데 닉네임이 hurryon이라 학생들은 이렇게 더 많이 부른다)께서
이 교재를 선택 한 것으로 보아 인터넷프로그래밍은 JSP나 ASP가 아닌 PHP로 할 것이라는 것을 알수 있었다.

다행스럽게도 군입대전에 PHP와 MySQL(phpMyAdmin으로 어설프게 써보기 했지만) 잠깐 만져 본데다가
여름방학때 알바한 곳에서 팀장님이 게시판 좀 분석해달라는 부탁때문에 몇번 건들여 봤는데
그 경험을 살릴수 있겠다 싶었다.

하지만!!
역시 '가라'로 배운건 어쩔수가 없었는지... 모르는 것만 수두룩......
어쨌건 그렇게 PHP와 MySQL을 배우며, 현재 방명록 제작에 이르게 되었다.......

일단 서평을 하자면... 나름 괜찮았다...
디자인도 좋고, 보기도 편하고....
다만 현재 들어와 잘쓰이지 않는 문법등은 따로 제시했으면 좋지 않았을까 하는 아쉬움이 조금 남았다.

방명록 만들기는 중간고사가 끝난 다음주 부터 시작 되었는데
교수님의 원본 소스를 분석하고 변형하는 형태로 시작되었다.

소스를 보기전에 기본 설정부터 소개하겠다.
먼저, 학교 실습 환경이다.
  * Apache webserver v1.3.31
    ->설정(c:\apache\conf\httpd.conf 파일)
ScriptAlias /php/ "c:/php5/"
AddType application/x-httpd-php .php
Action application/x-httpd-php "/php/php-cgi.exe"
SetEnv PHPRC C:/php5
  * PHP v5.0.2
    ->설정(c:\php5\php5.ini 파일)
register_globals=On
extension_dir = "C:\php5\ext"
extension=php_mysql.dll
  * MySQL v4.0.18
    ->설정(명령프롬프트에서 설정)
c:\mysql\bin> mysqld-nt --install
c:\mysql\bin> net start mysql
c:\mysql\bin> mysql

다음 본인의 PC에서의 설정이다.
개인적으로 C드라이브는 윈도우와 응용프로그램을 제외한 파일이 사용되는것을 꺼려하므로
D드라이브에 server폴더를 두어 한꺼번에 모아두었다.
운영체제가 Vista라 MySQL4.0이 실행되지 않으므로 5.0으로 대신 하였다.
  * Apache HTTP server v2.2
    ->설정(D:\server\apache\conf\httpd.conf 파일)
ScriptAlias /php/ "d:/Server/php5/"
AddType application/x-httpd-php .php
Action application/x-httpd-php "/php/php-cgi.exe"
SetEnv PHPRC D:/Server/php5
  * PHP v5.0.2
    ->설정(D:\server\php5\php5.ini 파일)
register_globals=On
extension_dir = "D:\server\php5\ext"
extension=php_mysql.dll
  * MySQL v5.0.67
    ->설정(명령프롬프트에서 설정)
d:\server\mysql\bin> mysqld-nt --install
d:\server\mysql\bin> net start mysql
d:\server\mysql\bin> mysql

다음은 MySQL 사용자 및 DB추가 구문이다.

create database php5_db;
use mysql;
insert into user (host, user, password) values ('localhost', 'php5', password('1234'));
insert into db values ('localhost', 'php5_db', 'php5', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y');
flush privileges;

잠시 설명하자면, create database php5_db는 php5_db라는 데이터베이스를 생성하며,
use mysql 쿼리문으로 mysql 데이터베이스를 선택하고 insert into user로 사용자추가,
insert into db로 php5_db를 php5사용자에게 연결시켜준다.
flush privileges를 해줌으로써 DB에 적용시킨다.

이제 준비는 끝났으며, 다음 소스를 사용하여 방명록을 작성하면 동작하게 된다.

소스의 원본은 Hurryon교수님의 페이지(http://www.hurryon.org/index.php/php_guestbook)에서 퍼온 것임을 미리 알린다...
<혹여나 저작권에 위배된다면 바로 삭제하겠습니다...>
 <?php
//
// ====================================================================================
// DB 접속에 필요한 사항을 설정합니다...
// mysql_connect 함수는 말그대로 MySQL 디비에 접속하는 것입니다.
// 온라인 게임을 하려면 게임서버에 접속해야 하는것과 마찬가지로 디비를 쓰려면
// 우선 접속을 해야겠지요......
//
// Host (서버주소 - localhost를 쓰면 됩니다.)
// User (디비를 쓸 수 있는 권한을 가진 유저 아이디를 씁니다.)
// Passwd (등록된 유저의 비밀번호를 씁니다.)..
//
// mysql_select_db 함수는 등록된 유저가 쓸 수 있는 디비를 선택하는 것입니다.
// MySQL에는 여러개의 DB를 만들 수 있거든요.그중 쓰고자 하는 하나를 선택하는 것입니다.
//
// 앞시간에 만든 디비와 비교해보면,
// Host = localhost , User = testuser , Passwd = mypass , DB = testdb 입니다.
// 위처럼 자신의 설정에 맞게 host,user,passwd,user_db 를 바꾸어 줍니다.
// ===================================================================================

$connect = mysql_connect("host","user","passwd") or die("SQL server에 연결할 수 없습니다.");
mysql_select_db("user_db",$connect);

// ===================================================================================
// die 는 말그대로 죽었단 뜻이죠. DB 가 죽어버렸는지-_- 응답을 안한다는 소리입니다.
// $connect 변수를 유심히 보세요. mysql_connect 함수의 결과가 $connect 변수에 저장되죠?
// 그런데 다음 mysql_select_db 에서도 $connect 변수가 쓰이고 있습니다.
// 이것은 $connect 변수가 MySQL에 들어가도 좋다는 출입증과 같은 역할이기 때문입니다.
// 그리고 만약 또 다른 MySQL 서버에 접속했다면(혹은 다른 아이디로)
// 이 연결과 위의 연결을 구별하기 위한 구별자역할도 합니다.
// ===================================================================================

// ================
// 게시판 환경설정
// ================

$scale = 5; // 한 페이지당 자료 수
$admin_ip = '127.0.0.1';  // 삭제시 필요한 관리자 IP
$html_allow = 0; // HTML 허용 여부(1 -> yes, 0 -> no)

// 방명록의 테이블 이름은 guestbook 입니다.

// ===================================================================================
// $mode 는 new, up, del 또는 NULL 의 값을 가집니다. ( NULL = 無 )
// $mode 가 new 라는 값을 가지면 새 글을 입력할 때
// $mode 가 up 이라는 값을 가지면 글을 DB에 저장할 때
// $mode 가 del 이라는 값을 가지면 글을 지울때 입니다.
// ===================================================================================

// ==========
// 글 지우기
// ==========

if ($mode == 'del') {
 
  if ($REMOTE_ADDR != $admin_ip) //$REMOTE_ADDR 은 접속자의 IP정보입니다.
  { // 관리자 IP와 접속자 IP가 다르므로 글 삭제 권한이 없다.
        echo("
        <script>
           window.alert('관리자만 지울 수 있습니다.')
        </script>");
     echo("<meta http-equiv='Refresh' content='0; URL=$PHP_SELF'>");
     exit;
  }
  else { //접속자 IP가 관리자 IP와 같으면 글을 지울 수 있는 권리가 있다.
     $que1 = "delete from guestbook where id=$id"; //SQL문을 만들고
     $result = mysql_query($que1,$connect); //SQL문을 실행한다.
  }
}

// =============
// 새 글 올리기
// =============

if ($mode == 'up') {
  if (!$name || !$comment) { //이름과 내용을 적으란 말야!! 적어!!!
     echo("
        <script>
           window.alert('이름과 남기실 말씀을 적어 주세요');
       history.go(-1);
    </script>");
     exit;
  }

  if (!$allow_html) { //HTML 입력을 허용하지 않으면
     $name = htmlspecialchars($name);              // HTML코드를 특수문자로 바꾸어버림
     $comment = htmlspecialchars($comment); // 예) <b> -> <b>
  }

// ===================================================================================
// htmlspecialchars 함수를 쓰면 HTML 코드가 적용되지 아니하고 코드를 그대로 출력해준다.
// addslashes 함수는 DB에 데이터를 입력할때 ' (작은따옴표) 같은 값들이 SQL 문에서
// 에러가 나지않고 입력되게 하기위한 배려이다.
// ===================================================================================

  $name = addslashes($name);
  $home = addslashes($home);
  $email = addslashes($email);
  $comment = addslashes($comment);

  $que1 = "insert into guestbook values ";
  $que1 .= "('','$name','$home','$email','$comment','$REMOTE_ADDR',now())";
  $result = mysql_query($que1,$connect);

  if ($result) { // DB에 입력이 잘되었다면..
     echo("<META http-equiv='Refresh' content='0; URL=$PHP_SELF'>");
     exit;
  }
  else { // DB에 데이터 입력중 오류가 발생한경우..
     echo("
        <script>
       window.alert('DB 오류가 발생하였습니다.');
       history.go(-1);
        </script>");
     exit;
  }
} //up end

// ==============
// 새 글 쓰기 폼
// ==============

if ($mode == 'new') { //새글쓰기 폼을 출력한다.

  echo("
     <FORM name='form' method='post' action='$PHP_SELF'>
     <TABLE border='0' cellspacing='1'>
     <TR>
     <TD width='109' bgcolor='#5485B6'><P align='center'><FONT face='굴림' size='2' color='#CDDAE4'>이름</FONT></TD>
     <TD width='541'><P>&nbsp;<INPUT type='text' name='name' SIZE=6 MAXLENGTHTH='20'></TD>
     </TR>
     <TR>
     <TD bgcolor='#5485B6'><P align='center'><FONT face='굴림' size='2' color='#CDDAE4'>HOMEPAGE</FONT></TD>
     <TD><P>&nbsp;http://<INPUT type='text' name='home' maxlength='40'></TD>
     </TR>
     <TR>
     <TD bgcolor='#5485B6'><P align='center'><FONT face='굴림' size='2' color='#CDDAE4'>Email 주소</FONT></TD>
     <TD><P>&nbsp;<INPUT type='text' name='email' size=20  maxlength='40'></TD>
     </TR>
     <TR>
     <TD bgcolor='#5485B6'><P align='center'><FONT face='굴림' size='2' color='#CDDAE4'>남기실 말씀</FONT></TD>
     <TD><P><TEXTAREA name='comment' rows='4' cols='35'></TEXTAREA></TD>
     </TR>
     <TR>
     <TD><P>&nbsp;</TD>
     <TD><P>&nbsp;<INPUT type='submit' name='submit' value='글올리기'></TD>
     </TR>
     </TABLE>
     <input type=hidden name=mode value='up'>
     </FORM>");
}

// =============
// 내용보여주기 
// =============

if (!$mode || $result) { //$mode 변수가 NULL 이면 입력된 내용을 출력한다.

     if (!$start) { $start = 0; }

      $que1 = "select DATE_FORMAT(reg_date,'Y.m.d'),id,comment,name";
      $que1 .= ",home,email,ip from guestbook order by id DESC";
      $result = mysql_query($que1,$connect);
      $total = mysql_affected_rows();

      // ================================================================
      // $que1  이라는 SQL문을 작성하고 SQL문을 실행한다.
      // $total 에는 검색된 자료의 수가 입력된다.
      // ================================================================


      for($i=$start ; $i<$start+$scale ; $i++) {  //  start 에서 scale 까지 만

         if ($i < $total) { // 전체 자료 개수까지만 출력
        mysql_data_seek($result,$i); //검색된 자료중 $i 번째글을 찾고
        $row = mysql_fetch_array($result); //$i번째글의 내용을 $row 변수에 배열로 저장합니다.
    
        $row[comment] = stripslashes($row[comment]) ; //addslashes 한값을 제거
            echo("
        <TABLE border='0' cellspacing='1'>
        <TR>
        <TD width='109' bgcolor='#5485B6'><P align='center'><FONT face='굴림' size='2' color='#CDDAE4'>
<a href=$PHP_SELF?mode=del&id=$row[id]><IMG src='./img/del.gif' width='22' height='13' border='0' alt='지우기'></a></FONT></TD>
        <TD width='541'><P><FONT face='굴림' size='2' color='#FAF1C7'>$row[0] from $row[ip]</FONT></TD>
        </TR>
        <TR>
            <TD width='109' bgcolor='#5485B6'><P align='center'><FONT face='굴림' size='2' color='#CDDAE4'>Name</FONT></TD>
        <TD width='541'><P><FONT face='굴림' size='2' color='#E7EEF5'>$row[name]</FONT></TD>
        </TR>
            <TR>
        <TD width='109' bgcolor='#5485B6'><P align='center'>
<FONT face='굴림' size='2' color='#CDDAE4'>Home / Email</FONT></TD>
        <TD width='541'><P>
<FONT face='굴림' size='2' color='#E7EEF5'>&nbsp;</FONT>");
        if ($row[email]) echo("<A href='mailto:$row[email]'><IMG SRC=./img/mail.gif BORDER=0 ALT='편지쓰기' align=center>
<FONT face='굴림' size='2' color='#E7EEF5'>$row[email]</FONT></A> &nbsp;");
        if ($row[home]) echo("<a href=http://$row[home]><IMG SRC=./img/home.gif BORDER=0 ALT='홈페이지' align=center>
<FONT face='굴림' size='2' color='#E7EEF5'>http://$row[home]</FONT></a>");
        echo("
            </TD>
        </TR>
        <TR>
        <TD width='109' bgcolor='#5485B6'><P align='center'><FONT face='굴림' size='2' color='#CDDAE4'>Comment&nbsp;</FONT></TD>
        <TD width='541'><P><FONT face='굴림' size='2' color='#E7EEF5'>$row[comment]</FONT></TD>
        </TR>
        <TR>
        <TD width='109'><P><HR size='1' noshade></TD>
        <TD width='541'><P><HR size='1' noshade></TD>
        </TR></TABLE>");
         }
     }
}

// ===================== 내용 보여주기 끝 ===========

if (!$mode || $result) {  // ==================== 하단 버튼 ==============
  echo("
  <center>
  <a href=$PHP_SELF?mode=new>
<IMG HEIGHT=30 WIDTH=30 SRC='./img/write.gif' VSPACE=0 HSPACE=0 ALIGN='TOP' BORDER=0 alt='방명록에 글쓰기'></a> ");

  $p_p = $start - $scale ; // 이전 페이지는 시작 글에서 $scale을 뺀값부터
  $n_p = $start + $scale ; // 다음 페이지는 시작 글에서 $scale을 더한값부터

  if ($p_p >= 0 && $mode != 'new') {
     echo("<a href='$PHP_SELF?start=$p_p'>
<IMG HEIGHT=30 WIDTH=30 SRC='./img/p-doc.gif' VSPACE=0 HSPACE=0 ALIGN='TOP' BORDER=0 alt='이전 페이지'></a> ");
  }

  if ($n_p < $total && $mode != 'new') {
     echo("<a href='$PHP_SELF?start=$n_p'>
<IMG HEIGHT=30 WIDTH=30 SRC='./img/n-doc.gif' VSPACE=0 HSPACE=0 ALIGN='TOP' BORDER=0 alt='다음 페이지'></a></center>");
  }
}

echo("
<p>                            
</BODY>
</HTML>");

?>

이것을 그대로 출력한 게시판은
따로 이미지가 없어서... 패스!!

일단 여기에 암호를 입력하여 글삭제가 가능 토록 하였다.
그후에 첫 과제가 이것을 이쁘게 디자인 하는 것!!!

방명록의 생김새를 조사한 결과 대부분의 방명록이 한 페이지 내에서 글쓰기가 이루어 짐을 착안!
한페이지에 모두 출력되도록 한 것이 아래 그림이다.

아......
이 얼마나 클래식한 디자인인가;;;;

이제부터 이 방명록이 어떻게 변하여 가는지를 소개하도록 하겠다....

이 방명록의 소스는 다음 글에 싣도록 하겠다.
일단 이 글은 여기까지........
Posted by Hugh.Kim