Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Hi! I need help for writing a game Tic-Tac-Toe by using c++ programming. 1.I nee

ID: 3665296 • Letter: H

Question

Hi! I need help for writing a game Tic-Tac-Toe by using c++ programming.

1.I need to draw the board using classes from the graphics library. ( i am using viusal studio 2013).

2. After that, I need to write about to ask the user to click on a empty spot on the board and display alternating X's and O's on the locations of those mouse clicks. After 9 clicks, the game ends.

3. Then, I need to display a "Game over" message somewhere on the viewing window and proceed to ask the user whether or not another game is to be played.

4. Finally, the program should end when the user enters a negative response to this question.

we may assume that 1. The user knows how to play the game. That is, once a location of the board is occupied, the user will not try to click on that location again unless a new game has started.

2. The game ends after 9 clicks regardless of whether or not there is an actual winner.

3. The player who draws the O's always gets to start the game (i.e., when the board is empty the first symbol displayed will be an O).

Also notice that at every individual game, exactly 5 O's and 4 X's are to be drawn.

*You should not repeat the procedure for drawing an O or an X more than necessary. You should loop the part of your code that performs the drawing rather than simply repeating your code multiple times.

Thank you for reading my long request:)

Explanation / Answer

#include typedef std::array tictactoe_status; tictactoe_status const strategy_x[] = { {1,0,0,0,0,0,0,0,0}, {1,2,0,0,1,0,0,0,0}, {1,2,2,0,1,0,0,0,1}, {1,2,0,2,1,0,0,0,1}, // ... }; tictactoe_status const strategy_o[] = { {2,0,0,0,1,0,0,0,0}, {2,2,1,0,1,0,0,0,0}, {2,2,1,2,1,0,1,0,0}, {2,2,1,0,1,2,1,0,0}, // ... }; tictactoe_status const strategy_x[] = { #include "strategy_x.h" }; tictactoe_status const strategy_o[] = { #include "strategy_o.h" }; // http://imgs.xkcd.com/comics/tic_tac_toe_large.png // similar version on http://upload.wikimedia.org/wikipedia/commons/d/de/Tictactoe-X.svg // 1 = X, 2 = O, 0 = unoccupied 1,0,0,0,0,0,0,0,0, 1,2,0,0,1,0,0,0,0, 1,2,2,0,1,0,0,0,1, 1,2,0,2,1,0,0,0,1, 1,2,0,0,1,2,0,0,1, std::vector strategy_o = { {2, 0, 0, 0, 1, 0, 0, 0, 0}, {2, 2, 1, 0, 1, 0, 0, 0, 0}, {2, 2, 1, 2, 1, 0, 1, 0, 0}, {2, 2, 1, 0, 1, 2, 1, 0, 0}, {2, 2, 1, 1, 1, 0, 2, 0, 0}, }; enum class tictactoe_player : char { none = 0, computer = 1, user = 2, }; class tictactoe_game { bool started; tictactoe_status status; std::set strategy; // ... }; bool is_started() const {return started;} bool is_victory(tictactoe_player const player) const {return is_winning(status, player);} bool is_finished() const { return is_full(status) || is_victory(tictactoe_player::user) || is_victory(tictactoe_player::computer); } bool is_winning(tictactoe_status const & status, tictactoe_player const player) const { auto mark = static_cast(player); return (status[0] == mark && status[1] == mark && status[2] == mark) || (status[3] == mark && status[4] == mark && status[5] == mark) || (status[6] == mark && status[7] == mark && status[8] == mark) || (status[0] == mark && status[4] == mark && status[8] == mark) || (status[2] == mark && status[4] == mark && status[6] == mark) || (status[0] == mark && status[3] == mark && status[6] == mark) || (status[1] == mark && status[4] == mark && status[7] == mark) || (status[2] == mark && status[5] == mark && status[8] == mark); } bool is_full(tictactoe_status const & status) const { return 0 == std::count_if(std::begin(status), std::end(status), [](int const mark){return mark == 0;}); } struct tictactoe_cell { int row; int col; tictactoe_cell(int r = INT_MAX, int c = INT_MAX):row(r), col(c) {} bool is_valid() const {return row != INT_MAX && col != INT_MAX;} }; std::pair const get_winning_line() const { auto mark = static_cast(tictactoe_player::none); if(is_victory(tictactoe_player::computer)) mark = static_cast(tictactoe_player::computer); else if(is_victory(tictactoe_player::user)) mark = static_cast(tictactoe_player::user); if(mark != 0) { if(status[0] == mark && status[1] == mark && status[2] == mark) return std::make_pair(tictactoe_cell(0,0), tictactoe_cell(0,2)); if(status[3] == mark && status[4] == mark && status[5] == mark) return std::make_pair(tictactoe_cell(1,0), tictactoe_cell(1,2)); if(status[6] == mark && status[7] == mark && status[8] == mark) return std::make_pair(tictactoe_cell(2,0), tictactoe_cell(2,2)); if(status[0] == mark && status[4] == mark && status[8] == mark) return std::make_pair(tictactoe_cell(0,0), tictactoe_cell(2,2)); if(status[2] == mark && status[4] == mark && status[6] == mark) return std::make_pair(tictactoe_cell(0,2), tictactoe_cell(2,0)); if(status[0] == mark && status[3] == mark && status[6] == mark) return std::make_pair(tictactoe_cell(0,0), tictactoe_cell(2,0)); if(status[1] == mark && status[4] == mark && status[7] == mark) return std::make_pair(tictactoe_cell(0,1), tictactoe_cell(2,1)); if(status[2] == mark && status[5] == mark && status[8] == mark) return std::make_pair(tictactoe_cell(0,2), tictactoe_cell(2,2)); } return std::make_pair(tictactoe_cell(), tictactoe_cell()); } void start(tictactoe_player const player) { strategy.clear(); if(player == tictactoe_player::computer) std::copy(std::begin(strategy_x), std::end(strategy_x), std::inserter(strategy, std::begin(strategy))); else if(player == tictactoe_player::user) std::copy(std::begin(strategy_o), std::end(strategy_o), std::inserter(strategy, std::begin(strategy))); status.assign(0); started = true; } bool move(tictactoe_cell const cell, tictactoe_player const player) { if(status[cell.row*3 + cell.col] == 0) { status[cell.row*3 + cell.col] = static_cast(player); if(is_victory(player)) { started = false; } return true; } return false; } tictactoe_cell move(tictactoe_player const player) { tictactoe_cell cell; strategy = lookup_strategy(); if(!strategy.empty()) { auto newstatus = lookup_move(); for(int i = 0; i < 9; ++i) { if(status[i] == 0 && newstatus[i]==static_cast(player)) { cell.row = i/3; cell.col = i%3; break; } } status = newstatus; if(is_victory(player)) { started = false; } } return cell; } std::set tictactoe_game::lookup_strategy() const { std::set nextsubstrategy; for(auto const & s : strategy) { bool match = true; for(int i = 0; i < 9 && match; ++i) { if(s[i] status[i]) diff++; } if(diff == 1) { newbest = s; if(is_winning(newbest, tictactoe_player::computer)) { break; } } } assert(newbest != empty_board); return newbest; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASS wc; // set the window class attributes // including pointer to a window procedure if (!::RegisterClass(&wc)) return FALSE; HWND wnd = ::CreateWindowEx(...); if(!wnd) return FALSE; ::ShowWindow(wnd, nCmdShow); MSG msg; while(::GetMessage(&msg, nullptr, 0, 0)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } return msg.wParam; } LRESULT WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_PAINT: { PAINTSTRUCT ps; HDC dc = ::BeginPaint(hWnd, &ps); // paint ::EndPaint(hWnd, &ps); } break; case WM_DESTROY: ::PostQuitMessage(0); return 0; case WM_COMMAND: { ... } break; } return ::DefWindowProc(hWnd, message, wParam, lParam); } class TicTacToeWindow : public Window { HANDLE hBmp0; HANDLE hBmpX; BITMAP bmp0; BITMAP bmpX; tictactoe_game game; void DrawBackground(HDC dc, RECT rc); void DrawGrid(HDC dc, RECT rc); void DrawMarks(HDC dc, RECT rc); void DrawCut(HDC dc, RECT rc); virtual void OnPaint(DeviceContext* dc) override; virtual void OnLeftButtonUp(int x, int y, WPARAM params) override; virtual void OnMenuItemClicked(int menuId) override; public: TicTacToeWindow(); virtual ~TicTacToeWindow() override; }; void TicTacToeWindow::OnPaint(DeviceContext* dc) { RECT rcClient; ::GetClientRect(hWnd, &rcClient); auto memdc = ::CreateCompatibleDC(*dc); auto membmp = ::CreateCompatibleBitmap(*dc, rcClient.right - rcClient.left, rcClient.bottom-rcClient.top); auto bmpOld = ::SelectObject(memdc, membmp); DrawBackground(memdc, rcClient); DrawGrid(memdc, rcClient); DrawMarks(memdc, rcClient); DrawCut(memdc, rcClient); ::BitBlt(*dc, rcClient.left, rcClient.top, rcClient.right - rcClient.left, rcClient.bottom-rcClient.top, memdc, 0, 0, SRCCOPY); ::SelectObject(memdc, bmpOld); ::DeleteObject(membmp); ::DeleteDC(memdc); } void TicTacToeWindow::DrawCut(HDC dc, RECT rc) { if(game.is_finished()) { auto streak = game.get_winning_line(); if(streak.first.is_valid() && streak.second.is_valid()) { int cellw = (rc.right - rc.left) / 3; int cellh = (rc.bottom - rc.top) / 3; auto penLine = ::CreatePen(PS_SOLID, 15, COLORREF(0x2222ff)); auto penOld = ::SelectObject(dc, static_cast(penLine)); ::MoveToEx( dc, rc.left + streak.first.col * cellw + cellw/2, rc.top + streak.first.row * cellh + cellh/2, nullptr); ::LineTo(dc, rc.left + streak.second.col * cellw + cellw/2, rc.top + streak.second.row * cellh + cellh/2); ::SelectObject(dc, penOld); } } } void TicTacToeWindow::OnMenuItemClicked(int menuId) { switch(menuId) { case ID_GAME_EXIT: ::PostMessage(hWnd, WM_CLOSE, 0, 0); break; case ID_GAME_STARTUSER: game.start(tictactoe_player::user); Invalidate(FALSE); break; case ID_GAME_STARTCOMPUTER: game.start(tictactoe_player::computer); game.move(tictactoe_player::computer); Invalidate(FALSE); break; } } void TicTacToeWindow::OnLeftButtonUp(int x, int y, WPARAM params) { if(game.is_started() && !game.is_finished()) { RECT rcClient; ::GetClientRect(hWnd, &rcClient); int cellw = (rcClient.right - rcClient.left) / 3; int cellh = (rcClient.bottom - rcClient.top) / 3; int col = x / cellw; int row = y / cellh; if(game.move(tictactoe_cell(row, col), tictactoe_player::user)) { if(!game.is_finished()) game.move(tictactoe_player::computer); Invalidate(FALSE); } } } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WindowClass wndcls(hInstance, L"TicTacToeWindowClass", MAKEINTRESOURCE(IDR_MENU_TTT), CallWinProc); TicTacToeWindow wnd; if(wnd.Create( wndcls.Name(), L"Fun C++: TicTacToe", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, hInstance)) { wnd.ShowWindow(nCmdShow); MSG msg; while(::GetMessage(&msg, nullptr, 0, 0)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } return msg.wParam; } return 0; } #pragma once #include "MainPage.g.h" #include "..Commongame.h" namespace TicTacToeWinRT { public ref class MainPage sealed { private: tictactoe_game game; // ... }; } void TicTacToeWinRT::MainPage::btnStartUser_Click(Object^ sender, RoutedEventArgs^ e) { ResetGame(); game.start(tictactoe_player::user); } void TicTacToeWinRT::MainPage::btnStartComputer_Click(Object^ sender, RoutedEventArgs^ e) { ResetGame(); game.start(tictactoe_player::computer); auto cell = game.move(tictactoe_player::computer); PlaceMark(cell, tictactoe_player::computer); } void TicTacToeWinRT::MainPage::PlaceMark(tictactoe_cell const cell, tictactoe_player const player) { auto image = ref new Image(); auto bitmap = ref new BitmapImage( ref new Uri(player == tictactoe_player::computer ? "ms-appx:///Assets/tttx.bmp" : "ms-appx:///Assets/ttt0.bmp")); bitmap->ImageOpened += ref new RoutedEventHandler( [this, image, bitmap, cell](Object^ sender, RoutedEventArgs^ e) { image->Width = bitmap->PixelWidth; image->Height = bitmap->PixelHeight; image->Visibility = Windows::UI::Xaml::Visibility::Visible; }); image->Source = bitmap; image->Visibility = Windows::UI::Xaml::Visibility::Collapsed; image->HorizontalAlignment = Windows::UI::Xaml::HorizontalAlignment::Center; image->VerticalAlignment = Windows::UI::Xaml::VerticalAlignment::Center; Grid::SetRow(image, cell.row); Grid::SetColumn(image, cell.col); board->Children->Append(image); } void TicTacToeWinRT::MainPage::ResetGame() { std::vector children; for(auto const & child : board->Children) { auto typeName = child->GetType()->FullName; if(typeName == "Windows.UI.Xaml.Controls.Image" || typeName == "Windows.UI.Xaml.Shapes.Line") { children.push_back(child); } } for(auto const & child : children) { unsigned int index; if(board->Children->IndexOf(child, &index)) { board->Children->RemoveAt(index); } } txtStatus->Text = nullptr; } void TicTacToeWinRT::MainPage::board_PointerReleased(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e) { if(game.is_started() && ! game.is_finished()) { auto cellw = board->ActualWidth / 3; auto cellh = board->ActualHeight / 3; auto point = e->GetCurrentPoint(board); auto row = static_cast(point->Position.Y / cellh); auto col = static_cast(point->Position.X / cellw); game.move(tictactoe_cell(row, col), tictactoe_player::user); PlaceMark(tictactoe_cell(row, col), tictactoe_player::user); if(!game.is_finished()) { auto cell = game.move(tictactoe_player::computer); PlaceMark(cell, tictactoe_player::computer); if(game.is_finished()) { DisplayResult( game.is_victory(tictactoe_player::computer) ? tictactoe_player::computer : tictactoe_player::none); } } else { DisplayResult( game.is_victory(tictactoe_player::user) ? tictactoe_player::user : tictactoe_player::none); } } } void TicTacToeWinRT::MainPage::DisplayResult(tictactoe_player const player) { Platform::String^ text = nullptr; switch (player) { case tictactoe_player::none: text = "It's a draw!"; break; case tictactoe_player::computer: text = "Computer wins!"; break; case tictactoe_player::user: text = "User wins!"; break; } txtStatus->Text = text; if(player != tictactoe_player::none) { auto coordinates = game.get_winning_line(); if(coordinates.first.is_valid() && coordinates.second.is_valid()) { PlaceCut(coordinates.first, coordinates.second); } } } void TicTacToeWinRT::MainPage::PlaceCut(tictactoe_cell const start, tictactoe_cell const end) { auto cellw = board->ActualWidth / 3; auto cellh = board->ActualHeight / 3; auto line = ref new Line(); line->X1 = start.col * cellw + cellw / 2; line->Y1 = start.row * cellh + cellh / 2; line->X2 = end.col * cellw + cellw / 2; line->Y2 = end.row * cellh + cellh / 2; line->StrokeStartLineCap = Windows::UI::Xaml::Media::PenLineCap::Round; line->StrokeEndLineCap = Windows::UI::Xaml::Media::PenLineCap::Round; line->StrokeThickness = 15; line->Stroke = ref new SolidColorBrush(Windows::UI::Colors::Red); line->Visibility = Windows::UI::Xaml::Visibility::Visible; Grid::SetRow(line, 0); Grid::SetColumn(line, 0); Grid::SetRowSpan(line, 3); Grid::SetColumnSpan(line, 3); board->Children->Append(line); }
Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote