📄 ztscards.c
字号:
{//鼠标按下点的空当没有牌
if (ColumnSelected < 8)
{//列对空当
i = CalcColumnCards (ColumnSelected);
SpaceLeft[m] = Cards[ColumnSelected][i];
Cards[ColumnSelected][i] = -1;
j = ColumnSelected;
ColumnSelected = -1;
DrawColumn (GetDC (hWnd), j, TRUE);
DrawSpaceLeft (GetDC (hWnd));
SweepWar (hWnd);
}
else
{//空当对空当
SpaceLeft[m] = SpaceLeft[ColumnSelected-8];
SpaceLeft[ColumnSelected-8] = -1;
ColumnSelected = -1;
DrawSpaceLeft (GetDC (hWnd));
}
}
else
{//鼠标按下点的空当有牌
if (bErrorMessage)
{
MessageBox (hWnd, "对不起,不能这样移牌。", "ZTS's 空当接龙", MB_OK | MB_ICONINFORMATION);
if (ColumnSelected < 8)
{
i = ColumnSelected;
ColumnSelected = -1;
DrawColumn (GetDC (hWnd), i, FALSE);
}
else
{
ColumnSelected = -1;
DrawSpaceLeft (GetDC (hWnd));
}
}
}
}
}
}
else if((yPos < nCardHeight) && (xPos > 348))
{//鼠标落在右边空当上
if (ColumnSelected != -1)
{//当前有牌选中
m = (xPos - 348) / nCardWidth;
m = 3 - m; //右边空当的顺序是从右往左
if (ColumnSelected < 8)
{//选中的是列中的牌
i = CalcColumnCards (ColumnSelected);
n = Cards[ColumnSelected][i];
if (SpaceRight[m] == -1)
SpaceRight[m] = (n % 4) - 4;
if ((SpaceRight[m] + 4) == n)
{
SpaceRight[m] = n;
Cards[ColumnSelected][i] = -1;
i = ColumnSelected;
ColumnSelected = -1;
DrawColumn (GetDC (hWnd), i, TRUE);
DrawSpaceRight (hWnd, GetDC (hWnd));
SweepWar (hWnd);
}
else
{
if (bErrorMessage)
{
MessageBox (hWnd, "对不起,不能这样移牌。", "ZTS's 空当接龙", MB_OK | MB_ICONINFORMATION);
i = ColumnSelected;
ColumnSelected = -1;
DrawColumn (GetDC (hWnd), i, FALSE);
}
}
}
else
{//选中的左边空当中的牌
n = SpaceLeft[ColumnSelected-8];
if (SpaceRight[m] == -1)
SpaceRight[m] = (n % 4) - 4;
if ((SpaceRight[m] + 4) == n)
{
SpaceRight[m] = n;
SpaceLeft[ColumnSelected-8] = -1;
ColumnSelected = -1;
DrawSpaceLeft (GetDC (hWnd));
DrawSpaceRight (hWnd, GetDC (hWnd));
SweepWar (hWnd);
}
else
{
if (bErrorMessage)
{
MessageBox (hWnd, "对不起,不能这样移牌。", "ZTS's 空当接龙", MB_OK | MB_ICONINFORMATION);
ColumnSelected = -1;
DrawSpaceLeft (GetDC (hWnd));
}
}
}
}
}
else if ((n > dxCard) && (yPos > nCardHeight+10))
{//鼠标落在某一列牌上
i = CalcColumnCards (m);
if (ColumnSelected == -1)
{//当前没有选中任何牌
if ((i != -1) && (yPos < (nCardHeight+10+dyCard*i+nCardHeight)))
{
ColumnSelected = m;
cdtDraw (GetDC (hWnd), (m+1)*dxCard+m*nCardWidth, i*dyCard+nCardHeight+10, Cards[m][i], mdHilite, RGB (0, 0x7a, 0));
}
}
else
{//当前已经选中了某一列牌
if (ColumnSelected >= 8)
{//已经选中的是左边空当,左边空当分别表示列 8,9,10,11
i = CalcColumnCards (m);
if ((Cards[m][0] == -1) | (IsMatch (Cards[m][i], SpaceLeft[ColumnSelected-8])))
{//空当中的牌可以拿下来放在列上
Cards[m][i+1] = SpaceLeft[ColumnSelected-8];
SpaceLeft[ColumnSelected-8] = -1;
ColumnSelected = -1;
DrawSpaceLeft (GetDC (hWnd));
DrawColumn (GetDC (hWnd), m, FALSE);
SweepWar (hWnd);
}
else
{//不能拿下来
if (bErrorMessage)
{
MessageBox (hWnd, "对不起,不能这样移牌。", "ZTS's 空当接龙", MB_OK | MB_ICONINFORMATION);
ColumnSelected = -1;
DrawSpaceLeft (GetDC (hWnd));
}
}
}
else
{//已经选中的是某一列牌,现在鼠标按下点是另一列牌
if (m == ColumnSelected)
{//如果再次选中这一列,则取消该列的选中状态
ColumnSelected = -1;
cdtDraw (GetDC (hWnd), (m+1)*dxCard+m*nCardWidth, i*dyCard+nCardHeight+10, Cards[m][i], mdFace, RGB (0, 0x7a, 0));
}
else
{
//先计算选中列下端有几张按规则排列的牌
i = CalcColumnCards (ColumnSelected);
j = i;
for ( ; j>=0; j--)
{
if (!IsMatch (Cards[ColumnSelected][j-1], Cards[ColumnSelected][j]))
break;
}
j = i - j + 1; //现在 j 中保存着选中列下端有几张按规则排列的牌
//再计算鼠标按下列的最下面一张牌能不能和上面那几张牌
//中的任意几张牌构成一个新的规则排列
if (Cards[m][0] == -1)
{
t = j - 1;
k = CalcColumnCards (m);
}
else
{
k = CalcColumnCards (m);
for (t=0; t<j; t++)
{
if (IsMatch (Cards[m][k], Cards[ColumnSelected][i-t]))
break;
}
}
if (t == j)
{//不能构成任何规则排列
if (bErrorMessage)
{
MessageBox (hWnd, "对不起,不能这样移牌。", "ZTS's 空当接龙", MB_OK | MB_ICONINFORMATION);
t = ColumnSelected;
ColumnSelected = -1;
DrawColumn (GetDC (hWnd), t, FALSE);
}
}
else
{//可以移动,可以移动的牌数目为 t+1
t++;
if ((k == -1) && (t != 1))
{//列对空列
k = DialogBoxParam (hInst, MAKEINTRESOURCE(DLG_MOVE), hWnd, DlgMoveProc, 0);
if (k == 1)
{
Cards[m][0] = Cards[ColumnSelected][i];
Cards[ColumnSelected][i] = -1;
t = ColumnSelected;
ColumnSelected = -1;
DrawColumn (GetDC (hWnd), t, TRUE);
DrawColumn (GetDC (hWnd), m , FALSE);
}
if (k == 2)
{
t = (t < CalcSpaceAll (TRUE)) ? t : CalcSpaceAll (TRUE);
for (j=0; j<t; j++)
{
Cards[m][j] = Cards[ColumnSelected][i-t+j+1];
Cards[ColumnSelected][i-t+j+1] = -1;
}
t = ColumnSelected;
ColumnSelected = -1;
DrawColumn (GetDC (hWnd), t, TRUE);
DrawColumn (GetDC (hWnd), m , FALSE);
}
SweepWar (hWnd);
}
else
{//列对列
if (CalcSpaceAll(FALSE) >= t)
{//空当够用
// m 表示鼠标按下的列,ColumnSelected 表示选中的列
// k 表示 m 列有几张牌,i 表示选中列有几张牌
// t 表示可以移动的牌数,j 用来循环移动 t 张牌
for (j=0; j<t; j++)
{
Cards[m][k+j+1] = Cards[ColumnSelected][i-t+j+1];
Cards[ColumnSelected][i-t+j+1] = -1;
}
t = ColumnSelected;
ColumnSelected = -1;
DrawColumn (GetDC (hWnd), t, TRUE);
DrawColumn (GetDC (hWnd), m , FALSE);
SweepWar (hWnd);
}
else
{//空当不够用
if (bErrorMessage)
{
wsprintf (buf, "要求移动 %d 张牌,当所剩空间只能够移动 %d 张牌", t, CalcSpaceAll(FALSE));
MessageBox (hWnd, buf, "ZTS's 空当接龙", MB_OK | MB_ICONINFORMATION);
t = ColumnSelected;
ColumnSelected = -1;
DrawColumn (GetDC (hWnd), t, FALSE);
}
}
}
}
}
}
}
}
}
//处理 WM_LBUTTONDBLCLK 消息///////////////////////////////////////////////////
void OnLbuttonDblclk (HWND hWnd, int xPos, int yPos)
{
int m, n, i, j;
m = xPos / (nCardWidth + dxCard);
n = xPos % (nCardWidth + dxCard);
if (bCanMouseDblclk && (n > dxCard))
{//表示鼠标按下点在列上,不再列于列之间的空隙上
i = CalcColumnCards (m);
if ((yPos > (nCardHeight+10)) && (yPos < (nCardHeight+10+dyCard*i+nCardHeight)))
{//表示鼠标按下点在牌上
for (j=0; j<4; j++)
if (SpaceLeft[j] == -1)
break;
ColumnSelected = -1;
if (j < 4)
{//表示有闲置空当
SpaceLeft[j] = Cards[m][i];
Cards[m][i] = -1;
DrawColumn (GetDC (hWnd), m, TRUE);
DrawSpaceLeft (GetDC (hWnd));
}
else//不管有没有闲置空当,都要取消选中状态
DrawColumn (GetDC (hWnd), m, FALSE);
SweepWar (hWnd);
}
}
}
//处理 WM_RBUTTONDOWN 消息/////////////////////////////////////////////////////
void OnRbuttonDown (HWND hWnd, int xPos, int yPos)
{
int i;
//计算鼠标右键按下点处于那一列,忽略列于列之间的空隙
nRX = xPos / (nCardWidth + dxCard);
//计算鼠标右键按下点相对于所处列的左边界的距离
nRY = xPos % (nCardWidth + dxCard);
if ((nRY > dxCard) && (yPos > nCardHeight+10))
{
//计算按下点下面的牌在当前列中的序号
nRY = (yPos - nCardHeight - 10) / dyCard;
//计算当前列一共有几张牌
i= CalcColumnCards (nRX);
if (nRY < i)
{//如果按下点下面的牌当前不可见
cdtDraw (GetDC (hWnd), (nRX+1)*dxCard+nRX*nCardWidth, nRY*dyCard+nCardHeight+10, Cards[nRX][nRY], mdFace, RGB (0, 0x7a, 0));
bRbuttonDown = TRUE;
SetCapture (hWnd);
}
}
}
//处理 WM_RBUTTONUP 消息///////////////////////////////////////////////////////
void OnRbuttonUp (HWND hWnd)
{
if (bRbuttonDown)
{//鼠标右键处于按下状态
bRbuttonDown = FALSE;
ReleaseCapture ();
//重画当前列,别的不需要重画,如果重画会有闪烁
DrawColumn (GetDC (hWnd), nRX, FALSE);
}
}
//“选择游戏号”对话框过程/////////////////////////////////////////////////////
BOOL CALLBACK DlgSelectNumProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int n;
switch (uMsg)
{
case WM_INITDIALOG:
SetDlgItemInt (hWnd, IDC_EDIT_NUM, nNum, 0);
SetFocus (GetDlgItem (hWnd, IDC_EDIT_NUM));
SendMessage (GetDlgItem (hWnd, IDC_EDIT_NUM), EM_SETSEL, 0, -1);
break;
case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDOK: //“确定”按钮
n = GetDlgItemInt (hWnd, IDC_EDIT_NUM, 0, 1);
if (n>0 && n<=32000)
{//如果输入的游戏号有效
nNum = n;
EndDialog (hWnd, TRUE);
}
else
{//输入的游戏号无效,则不关闭对话框重新输入
SetFocus (GetDlgItem (hWnd, IDC_EDIT_NUM));
SendMessage (GetDlgItem (hWnd, IDC_EDIT_NUM), EM_SETSEL, 0, -1);
}
return TRUE;
case IDCANCEL:
EndDialog (hWnd, FALSE);
return TRUE;
}
break;
}
return FALSE;
}
//“战况”对话框过程///////////////////////////////////////////////////////////
BOOL CALLBACK DlgScoreProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
char buf[256];
int i, j;
switch (uMsg)
{
case WM_INITDIALOG:
if ((cur_wins == 0) && (cur_losses == 0))
i = 0;
else
i = (100*cur_wins)/(cur_wins+cur_losses);
if ((won == 0) && (lost == 0))
j = 0;
else
j = (100*won)/(won+lost);
wsprintf (buf, "本局\t\t\t%d%%\n\t胜:\t\t%d\n\t负:\t\t%d\n\n总分\t\t\t%d%%\n\t胜:\t\t%d\n\t负:\t\t%d\n\n连续\n\t胜:\t\t%d\n\t负:\t\t%d\n\t当前:\t\t%d",
i, cur_wins, cur_losses, j, won, lost, wins, losses, streak);
if (stype)
lstrcat (buf, (stype == 1)?" 胜":" 负");
SetDlgItemText (hWnd, IDC_STATIC_SCORE, buf);
break;
case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDOK:
EndDialog (hWnd, TRUE);
return TRUE;
case IDC_BTN_CLEAR:
if (MessageBox (hWnd, "你真的要清除全部记录?", "ZTS's 空当接龙", MB_YESNO | MB_ICONQUESTION) == IDNO)
break;
cur_wins = 0;
cur_losses = 0;
won = 0;
lost = 0;
wins = 0;
losses = 0;
streak = 0;
stype = 0;
case IDCANCEL:
EndDialog (hWnd, FALSE);
return TRUE;
}
break;
}
return FALSE;
}
//“选项”对话框过程///////////////////////////////////////////////////////////
BOOL CALLBACK DlgOptionProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
if (bErrorMessage)
CheckDlgButton (hWnd, IDC_CHK_ERRORMSG, BST_CHECKED);
if (bQuickMoveCard)
CheckDlgButton (hWnd, IDC_CHK_QUICKMOVE, BST_CHECKED);
if (bCanMouseDblclk)
CheckDlgButton (hWnd, IDC_CHK_DBLCLK, BST_CHECKED);
break;
case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDOK:
if (IsDlgButtonChecked (hWnd, IDC_CHK_ERRORMSG) == BST_CHECKED)
bErrorMessage = TRUE;
else
bErrorMessage = FALSE;
if (IsDlgButtonChecked (hWnd, IDC_CHK_QUICKMOVE) == BST_CHECKED)
bQuickMoveCard = TRUE;
else
bQuickMoveCard = FALSE;
if (IsDlgButtonChecked (hWnd, IDC_CHK_DBLCLK) == BST_CHECKED)
bCanMouseDblclk = TRUE;
else
bCanMouseDblclk = FALSE;
EndDialog (hWnd, TRUE);
return TRUE;
case IDCANCEL:
EndDialog (hWnd, FALSE);
return TRUE;
}
break;
}
return FALSE;
}
//“移动到空当”对话框过程/////////////////////////////////////////////////////
BOOL CALLBACK DlgMoveProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
break;
case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDOK:
EndDialog (hWnd, 2);
return TRUE;
case IDC_BTN_MOVE1:
EndDialog (hWnd, 1);
return TRUE;
case IDCANCEL:
EndDialog (hWnd, 0);
return TRUE;
}
break;
}
return FALSE;
}
//“输了”对话框过程///////////////////////////////////////////////////////////
BOOL CALLBACK DlgLoseProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
break;
case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDOK:
if (IsDlgButtonChecked (hWnd, IDC_CHK_SAME) == BST_CHECKED)
EndDialog (hWnd, 2);
else
EndDialog (hWnd, 1);
return TRUE;
case IDCANCEL:
EndDialog (hWnd, 0);
return TRUE;
}
break;
}
return FALSE;
}
//“赢了”对话框过程///////////////////////////////////////////////////////////
BOOL CALLBACK DlgWinProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
break;
case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDOK:
if (IsDlgButtonChecked (hWnd, IDC_CHK_SELECT) == BST_CHECKED)
EndDialog (hWnd, 2);
else
EndDialog (hWnd, 1);
return TRUE;
case IDCANCEL:
EndDialog (hWnd, 0);
return TRUE;
}
break;
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -