// VC++ Hanoi.cpp #include "stdafx.h" #define _AFXDLL #include #include #include #include using namespace std; char nType = 1; int nStep = 0; void MoveType1(char x, char y) { cout << "Step(" << nStep++ << "): " << x << "->" << y << endl; Sleep(1000); } char plateArray[5][34] = { " <> ", " <<>> ", " <<<>>> ", " <<<<>>>> ", " <<<<<>>>>> ", }; int plate_count[3] = {5, 0, 0}; int from, to; char plate[11] = " "; void print_plateArray() { for (int r = 0; r < 5; r ++) { cout << plateArray[r] << endl; } cout << "----------------------------------" << endl; } void MoveType2(char x, char y) { from = x - 'A'; to = y - 'A'; for (int i = 0; i < 11; i ++) { plateArray[4 - plate_count[to]][to*11 + i] = plateArray[5 - plate_count[from]][from*11 + i]; plateArray[5 - plate_count[from]][from*11 + i] = ' '; } plate_count[from] --; plate_count[to] ++; cout << "Step(" << nStep++ << "): " << endl; print_plateArray(); Sleep(1000); } #define CANVAS_WIDTH 640 #define CANVAS_HEIGHTH 360 #define _LEFT 20 #define _TOP 20 #define PLATE_HEIGHT 28 CDC dcMem; CBitmap bmpMem; CDC cdcScreen; int plate_array[3][6] = { {80,70,60,50,40,30},{0,0,0,0,0,0},{0,0,0,0,0,0} }; int plate_num[3] = {6,0,0}; CFont font; CFont font2; void init3() { cdcScreen.CreateDC(_T("DISPLAY"), _T("DISPLAY"), _T("DISPLAY"), NULL); dcMem.CreateCompatibleDC(&cdcScreen); bmpMem.CreateCompatibleBitmap(&cdcScreen, CANVAS_WIDTH, CANVAS_HEIGHTH); CBitmap* pOldBmp = dcMem.SelectObject(&bmpMem); CRect rc(0,0,CANVAS_WIDTH,CANVAS_HEIGHTH); dcMem.FillSolidRect(&rc, (COLORREF)0x00ffffff); int ff = rc.Width(); dcMem.FillSolidRect(&rc, (COLORREF)0x00ffffff); LOGFONT logfont; memset(&logfont, 0, sizeof(logfont)); logfont.lfHeight = 72; logfont.lfWidth = 0; logfont.lfWeight = 400; logfont.lfCharSet = DEFAULT_CHARSET; _tcscpy(logfont.lfFaceName, _T("Goudy Stout")); font.CreateFontIndirect(&logfont); LOGFONT logfont2; memset(&logfont2, 0, sizeof(logfont2)); logfont2.lfHeight = 72; logfont2.lfWidth = 0; logfont2.lfWeight = 800; logfont2.lfCharSet = DEFAULT_CHARSET; _tcscpy(logfont2.lfFaceName, _T("Monotype Corsiva")); font2.CreateFontIndirect(&logfont2); cdcScreen.BitBlt(_LEFT, _TOP, CANVAS_WIDTH, CANVAS_HEIGHTH, &dcMem, 0, 0, SRCCOPY); } void drawPole() { CRect rc(0,0,CANVAS_WIDTH,CANVAS_HEIGHTH); dcMem.FillSolidRect(&rc, (COLORREF)0x00ffffff); dcMem.MoveTo(0, CANVAS_HEIGHTH * 3 / 4); dcMem.LineTo(CANVAS_WIDTH-1, CANVAS_HEIGHTH * 3 / 4); CRect rcPole(CANVAS_WIDTH/4-4,CANVAS_HEIGHTH / 4, CANVAS_WIDTH/4+4,CANVAS_HEIGHTH * 3 / 4+1); CBrush RedBrush(RGB(255,0,0)); dcMem.SelectObject(&RedBrush); dcMem.Rectangle(rcPole); rcPole.OffsetRect(CANVAS_WIDTH/4, 0); CBrush GreenBrush(RGB(0,255,0)); dcMem.SelectObject(&GreenBrush); dcMem.Rectangle(rcPole); rcPole.OffsetRect(CANVAS_WIDTH/4, 0); CBrush BlueBrush(RGB(0,0,255)); dcMem.SelectObject(&BlueBrush); dcMem.Rectangle(rcPole); CRect rcPoleNname(CANVAS_WIDTH/4-40, CANVAS_HEIGHTH * 3 / 4, CANVAS_WIDTH/4+40, CANVAS_HEIGHTH * 3 / 4+80); dcMem.SelectObject(&font); dcMem.SetTextColor(RGB(255,0,0)); dcMem.DrawText("A", &rcPoleNname, DT_CENTER | DT_SINGLELINE | DT_VCENTER); rcPoleNname.OffsetRect(CANVAS_WIDTH/4, 0); dcMem.SetTextColor(RGB(0, 255, 0)); dcMem.DrawText("B", &rcPoleNname, DT_CENTER | DT_SINGLELINE | DT_VCENTER); rcPoleNname.OffsetRect(CANVAS_WIDTH/4, 0); dcMem.SetTextColor(RGB(0,0,255)); dcMem.DrawText("C", &rcPoleNname, DT_CENTER | DT_SINGLELINE | DT_VCENTER); dcMem.SelectObject(&font2); dcMem.SetTextColor(RGB(255,0,255)); CString strTitle = "Tower of Hanoi"; dcMem.TextOut(10,0, strTitle); } void drawPlate(int pole, int idx) { int cx = (pole+1) * CANVAS_WIDTH/4; int ty = CANVAS_HEIGHTH * 3 / 4 - (idx+1)*PLATE_HEIGHT; CBrush grayBrush(RGB(80,80,80)); dcMem.SelectObject(&grayBrush); CRect rcPlate(cx-plate_array[pole][idx], ty, cx+plate_array[pole][idx], ty+PLATE_HEIGHT); dcMem.Ellipse(rcPlate); } void drawPlates(int pole_no_draw = -1, int idx_no_draw = -1) { for (int pole = 0; pole < 3; pole ++) { for (int idx = 0; idx < plate_num[pole]; idx ++) { if (pole == pole_no_draw && idx == idx_no_draw) continue; drawPlate(pole, idx); } } } void MoveType3(char x, char y) { int wt = 50; int from = x - 'A'; int to = y - 'A'; int num_from = plate_num[from]; int cx_from = (from+1) * CANVAS_WIDTH/4; int cx_to = (to+1) * CANVAS_WIDTH/4; int ty_from = CANVAS_HEIGHTH * 3 / 4 - (plate_num[from]+1)*PLATE_HEIGHT; int ty_to = CANVAS_HEIGHTH * 3 / 4 - (plate_num[to]+1)*PLATE_HEIGHT; int toptop = CANVAS_HEIGHTH * 3 / 4 - 8*PLATE_HEIGHT; int px = (from+1) * CANVAS_WIDTH/4; int py = ty_from; do { CRect rc(0,0,CANVAS_WIDTH,CANVAS_HEIGHTH); dcMem.FillSolidRect(&rc, (COLORREF)0x00ffffff); drawPole(); drawPlates(from, num_from-1); CRect rcPlate(px-plate_array[from][num_from-1], py, px+plate_array[from][num_from-1], py+PLATE_HEIGHT); dcMem.Ellipse(rcPlate); cdcScreen.BitBlt(_LEFT, _TOP, CANVAS_WIDTH, CANVAS_HEIGHTH, &dcMem, 0, 0, SRCCOPY); py -= PLATE_HEIGHT / 4; Sleep(wt); } while (py > toptop); do { CRect rc(0,0,CANVAS_WIDTH,CANVAS_HEIGHTH); dcMem.FillSolidRect(&rc, (COLORREF)0x00ffffff); drawPole(); drawPlates(from, num_from-1); CRect rcPlate(px-plate_array[from][num_from-1], py, px+plate_array[from][num_from-1], py+PLATE_HEIGHT); dcMem.Ellipse(rcPlate); cdcScreen.BitBlt(_LEFT, _TOP, CANVAS_WIDTH, CANVAS_HEIGHTH, &dcMem, 0, 0, SRCCOPY); px += (to-from) / abs(to-from) * 10; Sleep(wt); } while (abs(px - cx_to) > 10); px = cx_to; do { CRect rc(0,0,CANVAS_WIDTH,CANVAS_HEIGHTH); dcMem.FillSolidRect(&rc, (COLORREF)0x00ffffff); drawPole(); drawPlates(from, num_from-1); CRect rcPlate(px-plate_array[from][num_from-1], py, px+plate_array[from][num_from-1], py+PLATE_HEIGHT); dcMem.Ellipse(rcPlate); cdcScreen.BitBlt(_LEFT, _TOP, CANVAS_WIDTH, CANVAS_HEIGHTH, &dcMem, 0, 0, SRCCOPY); py += PLATE_HEIGHT / 4; Sleep(wt); } while (py < ty_to); plate_array[to][plate_num[to]] = plate_array[from][plate_num[from]-1]; plate_array[from][plate_num[from]-1] = 0; plate_num[from] --; plate_num[to] ++; CRect rc(0,0,CANVAS_WIDTH,CANVAS_HEIGHTH); dcMem.FillSolidRect(&rc, (COLORREF)0x00ffffff); drawPole(); drawPlates(); cdcScreen.BitBlt(_LEFT, _TOP, CANVAS_WIDTH, CANVAS_HEIGHTH, &dcMem, 0, 0, SRCCOPY); Sleep(wt); } void Move(char x, char y) { if (nType == 1) MoveType1(x, y); else if (nType == 2) MoveType2(x, y); else MoveType3(x, y); } void TowerHanoi(int n, char x, char y, char z) { if (n > 1) { TowerHanoi(n - 1, x, z, y); Move(x, z); TowerHanoi(n - 1, y, x, z); } else Move(x, z); } int main(int argc, char* argv[]) { nType = 1; TowerHanoi(3, 'A', 'B', 'C'); nType = 2; nStep = 0; print_plateArray(); TowerHanoi(5, 'A', 'B', 'C'); nType = 3; nStep = 0; init3(); TowerHanoi(6, 'A', 'B', 'C'); return 0; }