3.77us Solver(2.8G CPU, TestCase:17Sodoku)

Programs which generate, solve, and analyze Sudoku puzzles

Re: 3.77us Solver(2.8G CPU, TestCase:17Sodoku)

Postby zhouyundong_2012 » Fri Sep 02, 2016 11:04 am

#ifndef __Button_h__
#define __Button_h__

#include "Sprite.h"

enum {
BTN_NORMAL,
BTN_FOCUSED,
BTN_PRESSED,
BTN_DISABLE,
};

class CButton : public CSprite {
public:
CButton();
CButton(CImage *pImage, CRect xDrawRect, CRect xSrcRect, int nDepth);
virtual ~CButton();

public:
virtual void Set(CImage *pImage, CRect xDrawRect, CRect xSrcRect, int nDepth);
virtual void SetDrawRect(CRect xDrawRect);
virtual void SetSrcRect(CRect xSrcRect);
void SetSrcPos(CPoint xSrcPos);
void SetSrcPos(int x, int y);
virtual void Disable(bool bDisable = true);

public:
CObject *FindObject(const CPoint& point);
CObject *FindExcept(const CPoint& point, CObject *pExcept);

public:
void OnLoseFocus();
void OnLButtonDown(UINT nFlags, CPoint point);
void OnLButtonUp(UINT nFlags, CPoint point);
bool OnMouseEnter(UINT nFlags, CPoint point);
bool OnMouseLeave(UINT nFlags, CPoint point);
void OnLClick(UINT nFlags, CPoint point);
void OnRClick(UINT nFlags, CPoint point);
void OnMClick(UINT nFlags, CPoint point);

protected:
virtual void SetMapStyle();
virtual void SetMapSrcPos();

protected:
CRect m_xSrcRect; //映射源
int m_nMapStyle; //映射类型
int m_nStatus; //按钮状态
};

inline void CButton::SetSrcPos(CPoint xSrcPos)
{
SetSrcPos(xSrcPos.x, xSrcPos.y);
}

#endif
zhouyundong_2012
 
Posts: 148
Joined: 10 February 2012

Re: 3.77us Solver(2.8G CPU, TestCase:17Sodoku)

Postby zhouyundong_2012 » Fri Sep 02, 2016 11:05 am

#ifndef __Dialog_h__
#define __Dialog_h__

class CDialog : public CPanel {
public:
CDialog();
CDialog(CImage *pImage, CPoint xDrawPos, CSize xSize);
CDialog(CImage *pImage, CPoint xDrawPos, CPoint xSrcPos, CSize xSize);
virtual ~CDialog();

public:
virtual INT_PTR DoModal();

protected:
virtual BOOL PreTranslateMessage(MSG *msg);
virtual BOOL OnIdle(long count);
virtual int Run();
virtual void OnClose();

protected:
virtual INT_PTR DialogResult();

protected:
CObject *m_pActived;
};

inline BOOL CDialog::OnIdle(long count)
{
return count >= 100;
}

inline INT_PTR CDialog::DialogResult()
{
return NULL;
}

#endif
zhouyundong_2012
 
Posts: 148
Joined: 10 February 2012

Re: 3.77us Solver(2.8G CPU, TestCase:17Sodoku)

Postby zhouyundong_2012 » Fri Sep 02, 2016 11:05 am

#ifndef __WarCraft_h__
#define __WarCraft_h__

#include "Button.h"

class CWarCraft : public CButton {
public:
CWarCraft();
CWarCraft(CImage *pImage, CRect xDrawRect, CRect xSrcRect, int nDepth);
virtual ~CWarCraft();

public:
void SetKind(int nKind);
int GetKind() const;

public:
bool IsSelected() const;
void OnSelect();
void UnSelect();

public:
virtual bool RectIn(const CRect& rect);
virtual void OnLClick(UINT nFlags, CPoint point);
virtual void OnLDblClk(UINT nFlags, CPoint point);

protected:
int m_nKind;
bool m_bSelected;
};

inline void CWarCraft::SetKind(int nKind)
{
m_nKind = nKind;
}

inline int CWarCraft::GetKind() const
{
return m_nKind;
}

inline bool CWarCraft::IsSelected() const
{
return m_bSelected;
}

#endif
zhouyundong_2012
 
Posts: 148
Joined: 10 February 2012

Re: 3.77us Solver(2.8G CPU, TestCase:17Sodoku)

Postby zhouyundong_2012 » Fri Sep 02, 2016 11:05 am

#include "StdAfx.h"

static short g_shLeft;
static short g_shAdvance;
static short g_shTop;
static short g_shHeight;

static TFontStyle g_tScanFS;
static TFontStyle g_tDrawFS;

inline void UpdateFaceID(TFontStyle& tFontStyle)
{
//由FaceName和Style决定了FaceID
tFontStyle.tScalerRec.face_id = g_pZText->GetFaceID(tFontStyle.szFaceName, tFontStyle.byStyle);
}

static int GetChar(const TCHAR *pIn, char *chOut, int nPos)
{
*chOut = pIn[nPos];
return nPos + 1;
}

static int GetShort(const TCHAR *pIn, short *shOut, int nPos)
{
*shOut = (pIn[nPos] << 8) + pIn[nPos + 1];
return nPos + 2;
}

static int GetColor(const TCHAR *pIn, COLORREF *color, int nPos)
{
*color = BGRA(pIn[nPos], pIn[nPos + 1], pIn[nPos + 2], pIn[nPos + 3]);
return nPos + 4;
}

static int GetString(const TCHAR *pIn, TCHAR *pOut, int nPos, int L)
{
wcscpy_s(pOut, L, pIn + nPos);
return nPos + L;
}

static int GetFamily(const TCHAR *pIn, char *str, int nPos, int L)
{
TCHAR pOut[LF_FACESIZE];

wcscpy_s(pOut, L + 1, pIn + nPos);
WideCharToMultiByte(CP_ACP, 0, pOut, -1, str, LF_FACESIZE, NULL, NULL);

return nPos + L;
}

CTextBlk::CTextBlk() : CPanel()
{
m_bMultiLine = false;
m_nHeight = 0;
m_nBaseLine = 0;

m_pImage = NULL;
m_xPencil.x = 0;
m_xPencil.y = 0;
}

CTextBlk::CTextBlk(bool bMultiLine, int nHeight, CPoint xDrawPos, CSize xSize, int nDepth)
: CPanel(NULL, xDrawPos, xSize, nDepth)
{
m_bMultiLine = bMultiLine;
m_nHeight = nHeight;
m_nBaseLine = (m_nHeight + 9) / 10;

m_pImage = NULL;
m_xPencil.x = 0;
m_xPencil.y = 0;
}

CTextBlk::~CTextBlk()
{
delete m_pImage;
m_pImage = NULL;
}

bool CTextBlk::Initial()
{
if (!CPanel::Initial())
return false;

m_pImage = new CImage(m_xSize.cx, m_xSize.cy);
return m_pImage != NULL;
}

bool CTextBlk::Release()
{
CPanel::Release();

delete m_pImage;
m_pImage = NULL;
return true;
}

void CTextBlk::Rebuild()
{
}

void CTextBlk::Set(bool bMultiLine, int nHeight, CPoint xDrawPos, CSize xSize, int nDepth)
{
m_bMultiLine = bMultiLine;
m_nHeight = nHeight;
m_xDrawPos = xDrawPos;
m_xSize = xSize;
m_nDepth = nDepth;
m_nBaseLine = (m_nHeight + 9) / 10;
m_xPencil.x = 0;
m_xPencil.y = 0;
AllocImage(m_xSize.cx, m_xSize.cy);
}

void CTextBlk::SetHeight(int nHeight)
{
m_nHeight = nHeight;
m_nBaseLine = (m_nHeight + 9) / 10;
m_xPencil.x = 0;
m_xPencil.y = 0;
AllocImage(m_xSize.cx, m_xSize.cy);
}

void CTextBlk::SetRotate(FT_Face &face)
{
float fAngle = 10.0;
float fRadian = (float)(fAngle / 180.0 * 3.14159);

FT_Matrix matrix;
matrix.xx = (FT_Fixed)( cos(fRadian) * 0x10000L);
matrix.xy = (FT_Fixed)(-sin(fRadian) * 0x10000L);
matrix.yx = (FT_Fixed)( sin(fRadian) * 0x10000L);
matrix.yy = (FT_Fixed)( cos(fRadian) * 0x10000L);

FT_Set_Transform(face, &matrix, NULL);
}

void CTextBlk::InitialFontStyle(TFontStyle &tFontStyle, LOGFONT &logFont)
{
tFontStyle.byStyle = TS_NORMAL;

WideCharToMultiByte(CP_ACP, 0, logFont.lfFaceName, -1, tFontStyle.szFaceName, LF_FACESIZE, NULL, NULL);

UpdateFaceID(tFontStyle);
tFontStyle.tScalerRec.width = logFont.lfWidth;
tFontStyle.tScalerRec.height = logFont.lfHeight;
tFontStyle.tScalerRec.pixel = 1;

g_pZText->SetSpaceWidth(logFont.lfWidth);
}

FTC_SBit CTextBlk::GetBitmap(TCHAR tch, FTC_ScalerRec &tScalerRec)
{
FTC_Scaler pSelectedIC;
FTC_SBit bitmap;

int glyph_index = FTC_CMapCache_Lookup(g_pZText->GetCMapCache(), tScalerRec.face_id, -1, tch);
//找不到时以空格代替
if (glyph_index == 0)
glyph_index = FTC_CMapCache_Lookup(g_pZText->GetCMapCache(), tScalerRec.face_id, -1, _T(' '));
if (glyph_index)
pSelectedIC = &tScalerRec;

FTC_SBitCache_LookupScaler(g_pZText->GetSBitCache(), pSelectedIC, FT_LOAD_DEFAULT,
glyph_index, &bitmap, (FTC_Node *)NULL);

return bitmap;
}

void CTextBlk::AdjustBitmap(FTC_SBit bitmap)
{
g_shLeft = bitmap->left;
g_shAdvance = bitmap->xadvance;

//空白符号调整为默认值
if (bitmap->width == 0xFF)
g_shAdvance = g_pZText->GetSpaceWidth();

//调整左承载
if (g_shLeft < 0)
g_shLeft = 0;

//旋转调整
if (bitmap->width != 0xFF)
{
if (g_shLeft + bitmap->width > g_shAdvance)
{
g_shAdvance = g_shLeft + bitmap->width;
g_shLeft >>= 1;
}
}

g_shTop = bitmap->top;
g_shHeight = bitmap->height;

if (m_nHeight != 0)
{
//调整上承载
if (bitmap->height - m_nBaseLine > g_shTop)
g_shTop = bitmap->height - m_nBaseLine;
if (g_shTop > m_nHeight - m_nBaseLine)
g_shTop = m_nHeight - m_nBaseLine;

//调整高度
if (m_nHeight < g_shHeight)
g_shHeight = m_nHeight;
}
}

bool CTextBlk::PenAdvance(CRect &rect, int nXSpace, int nYSpace, FTC_SBit bitmap)
{
if (m_xPencil.x + g_shAdvance + nXSpace > rect.Width())
{
if (!m_bMultiLine)
return false;
m_xPencil.x = 0;
m_xPencil.y += m_nHeight + nYSpace;
if (m_xPencil.y + m_nBaseLine > rect.Height())
return false;
}
return true;
}

void CTextBlk::FillGlyph(CRect &rect, int nWidth, int nHeight, int nYBearing, COLORREF bkcolor)
{
for (int y = m_xPencil.y - nYBearing; y < m_xPencil.y - nYBearing + nHeight && y < rect.bottom; y++)
{
int *p = (int *)m_pImage->GetBits(m_xPencil.x, y);
for (int x = m_xPencil.x; x < m_xPencil.x + nWidth && x < rect.right; x++)
*p++ = bkcolor;
}
}

void CTextBlk::_DrawMonoGlyph(FTC_SBit bitmap, bool transparent, COLORREF color)
{
for (int y = 0; y < g_shHeight; y++)
{
int *p = (int *)m_pImage->GetBits(m_xPencil.x + g_shLeft, m_xPencil.y - g_shTop + y);
const byte *q = bitmap->buffer + y * bitmap->pitch;

if (transparent)
{
for (int x = 0; x < bitmap->width; x++)
{
if (q[x >> 3] & (0x80 >> (x & 7)))
*p++ = color; //前景色
else
*p++ = 0; //通透
}
}
else
{
for (int x = 0; x < bitmap->width; x++)
{
if (q[x >> 3] & (0x80 >> (x & 7)))
*p++ = color; //前景色
else
*p++; //背景色
}
}
}
}

void CTextBlk::_DrawGrayGlyph(FTC_SBit bitmap, bool transparent, COLORREF color)
{
byte b = GetBValue(color);
byte g = GetGValue(color);
byte r = GetRValue(color);

for (int y = 0; y < g_shHeight; y++)
{
byte *p = (byte *)m_pImage->GetBits(m_xPencil.x + g_shLeft, m_xPencil.y - g_shTop + y);
const byte *q = bitmap->buffer + y * bitmap->pitch;

if (transparent)
{
for (int x = 0; x < bitmap->width; x++)
{
byte gray = *q++;
*p++ = b;
*p++ = g;
*p++ = r;
*p++ = gray;
}
}
else
{
for (int x = 0; x < bitmap->width; x++)
{
//不透明时与指定背景色合成
byte gray = *q++;
alpha_composite(*p++, b, gray, *p);
alpha_composite(*p++, g, gray, *p);
alpha_composite(*p++, r, gray, *p);
*p++;
}
}
}
}

void CTextBlk::DrawGlyph(FTC_SBit bitmap, bool transparent, COLORREF color)
{
if (bitmap->format == FT_PIXEL_MODE_MONO)
{
_DrawMonoGlyph(bitmap, transparent, color);
}
else
{
_DrawGrayGlyph(bitmap, transparent, color);
}
}

void CTextBlk::ClearText()
{
m_xPencil.x = 0;
m_xPencil.y = 0;

ClearImage();
g_pZ2coo->Redraw(this);
}

int CTextBlk::OutText(const TCHAR *lpText, int nLength, HFONT hFont, bool transparent,
COLORREF color, COLORREF bkcolor, int nXSpace, int nYSpace)
{
m_pImage->Clear();

//获取区域限制
CRect rect;
GetRect(&rect);

m_xPencil.x = 0;
m_xPencil.y = 0;

//设置指定的FontStyle
LOGFONT logFont;
GetObject(hFont, sizeof(logFont), &logFont);

InitialFontStyle(g_tDrawFS, logFont);

//初始化到行高十分之九的位置
m_xPencil.y = m_nHeight - m_nBaseLine;

FTC_SBit bitmap;
for (int i = 0; i < nLength; i++)
{
if (lpText[i] == _T('\n'))
goto Exit;

bitmap = GetBitmap(lpText[i], g_tDrawFS.tScalerRec);
AdjustBitmap(bitmap);

//判断是否超过一行
if (!PenAdvance(rect, nXSpace, nYSpace, bitmap))
goto Exit;

if (!transparent)
{
//不透明时,填充背景色
FillGlyph(rect, g_shAdvance + nXSpace, m_nHeight, m_nHeight - m_nBaseLine, bkcolor);
}
DrawGlyph(bitmap, transparent, color);
m_xPencil.x += g_shAdvance + nXSpace;
}

Exit:
g_pZ2coo->Redraw(this);

m_xPencil.y += m_nBaseLine;
return m_xPencil.y;
}

int CTextBlk::GetTextLength()
{
int nTextLength = 0;

//设置指定的FontStyle
LOGFONT logFont;
GetObject(m_hFont, sizeof(logFont), &logFont);

InitialFontStyle(g_tDrawFS, logFont);

FTC_SBit bitmap;
for (int i = 0; i < wcslen(m_wcsText.c_str()); i++)
{
if (m_wcsText[i] == _T('\n'))
goto Exit;

bitmap = GetBitmap(m_wcsText[i], g_tDrawFS.tScalerRec);
AdjustBitmap(bitmap);

nTextLength += g_shAdvance + m_nXSpace;
}

Exit:
return nTextLength;
}

int CTextBlk::ExtOutText(const TCHAR *lpText, int nLength)
{
m_pImage->Clear();

//获取区域限制
CRect rect;
GetRect(&rect);

m_xPencil.x = 0;
m_xPencil.y = 0;

//设置默认的FontStyle
LOGFONT logFont;
GetObject(g_pZText->GetDefaultFont(), sizeof(logFont), &logFont);

InitialFontStyle(g_tDrawFS, logFont);

//透明,颜色,背景色
bool transparent = true;
COLORREF color = BGRA(0, 0, 0, 255);
COLORREF bkcolor = BGRA(255, 255, 255, 255);

//初始化到行高十分之九的位置
m_xPencil.y = m_nHeight - m_nBaseLine;

//字间距,行间距
int nXSpace = 0;
int nYSpace = 0;

short T, L;
int nPos = 0;
while (nPos < nLength)
{
nPos = GetShort(lpText, &T, nPos);
nPos = GetShort(lpText, &L, nPos);
switch (T)
{
case TF_TRANSPARENT:
nPos = GetChar(lpText, (char *)&transparent, nPos);
break;
case TF_COLOR:
nPos = GetColor(lpText, &color, nPos);
break;
case TF_BKCOLOR:
nPos = GetColor(lpText, &bkcolor, nPos);
break;
case TF_X_SPACE:
nPos = GetShort(lpText, (short *)&nXSpace, nPos);
break;
case TF_Y_SPACE:
nPos = GetShort(lpText, (short *)&nYSpace, nPos);
break;
case TF_TEXT:
FTC_SBit bitmap;
for (int i = nPos; i < nPos + L; i++)
{
if (lpText[i] == _T('\n'))
{
if (!m_bMultiLine)
goto Exit;
m_xPencil.x = 0;
m_xPencil.y += m_nHeight + nYSpace;
if (m_xPencil.y + m_nBaseLine > rect.Height())
goto Exit;
continue;
}
bitmap = GetBitmap(lpText[i], g_tDrawFS.tScalerRec);
AdjustBitmap(bitmap);

//判断是否超过一行
if (!PenAdvance(rect, nXSpace, nYSpace, bitmap))
goto Exit;

if (!transparent)
{
//不透明时,填充背景色
FillGlyph(rect, g_shAdvance + nXSpace, m_nHeight, m_nHeight - m_nBaseLine, bkcolor);
}
DrawGlyph(bitmap, transparent, color);
m_xPencil.x += g_shAdvance;
}
nPos += L; //L个字符
break;
default:
nPos += L;
break;
}
}

Exit:
g_pZ2coo->Redraw(this);

m_xPencil.y += m_nBaseLine;
return m_xPencil.y;
}

int CTextBlk::EnhOutText(const TCHAR *lpText, int nLength)
{
m_pImage->Clear();

//获取区域限制
CRect rect;
GetRect(&rect);

m_xPencil.x = 0;
m_xPencil.y = 0;

//设置默认的FontStyle
LOGFONT logFont;
GetObject(g_pZText->GetDefaultFont(), sizeof(logFont), &logFont);

InitialFontStyle(g_tScanFS, logFont);
InitialFontStyle(g_tDrawFS, logFont);

//透明,颜色,背景色
bool transparent = true;
COLORREF color = BGRA(0, 0, 0, 255);
COLORREF bkcolor = BGRA(255, 255, 255, 255);

//从nTagPos处开始解析,跳过nTagSkip个字符
int nTagPos = 0, nTagNext;
int nTagSkip = 0, nTagCurr;

//预处理行的最大高度,基准位置,最大下行距离,字符宽度
int nMaxHeight;
int nYBearing;
int nMaxBottom;
int nTotalWidth;

//字间距,行间距
int nXSpace = 0;
int nYSpace = 0;

short T, L;
while (nTagPos < nLength)
{
nMaxHeight = 0;
nYBearing = 0;
nMaxBottom = 0;
nTotalWidth = 0;

nTagCurr = nTagSkip; //记录当前解析位置

int nPos = nTagPos;
while (nPos < nLength)
{
nTagNext = nPos; //下一行从nTagNext处开始解析

nPos = GetShort(lpText, &T, nPos);
nPos = GetShort(lpText, &L, nPos);
switch (T)
{
case TF_TRANSPARENT:
case TF_COLOR:
case TF_BKCOLOR:
nPos += L; //必须跳过
break;
case TF_WIDTH:
nPos = GetShort(lpText, (short *)&g_tScanFS.tScalerRec.width, nPos);
break;
case TF_HEIGHT:
nPos = GetShort(lpText, (short *)&g_tScanFS.tScalerRec.height, nPos);
break;
case TF_FAMILY:
nPos = GetFamily(lpText, g_tScanFS.szFaceName, nPos, L);
UpdateFaceID(g_tScanFS);
break;
case TF_STYLE:
nPos = GetChar(lpText, (char *)&g_tScanFS.byStyle, nPos);
UpdateFaceID(g_tScanFS);
break;
case TF_X_SPACE:
nPos = GetShort(lpText, (short *)&nXSpace, nPos);
break;
case TF_Y_SPACE:
nPos = GetShort(lpText, (short *)&nYSpace, nPos);
break;
case TF_TEXT:
for (int i = max(nPos, nTagSkip); i < nPos + L; i++)
{
if (lpText[i] == _T('\n'))
{
//包括换行符
nTagSkip = i + 1;

//空行使用当前行高
if (nMaxHeight == 0)
{
nMaxHeight = g_tScanFS.tScalerRec.height;
nMaxBottom = 0;
nYBearing = g_tScanFS.tScalerRec.height;
}
goto Draw;
}
FTC_SBit bitmap = GetBitmap(lpText[i], g_tScanFS.tScalerRec);
AdjustBitmap(bitmap);

//判断是否超过一行
if (nTotalWidth + g_shAdvance + nXSpace > rect.Width())
{
//不包括当前字符
nTagSkip = i;
goto Draw;
}

nTotalWidth += g_shAdvance + nXSpace; //宽度累加
if (nMaxHeight < bitmap->height) //最大高度
nMaxHeight = bitmap->height;
if (nYBearing < bitmap->top) //基准位置
nYBearing = bitmap->top;
if (nMaxBottom < bitmap->height - bitmap->top) //最大下行距离
nMaxBottom = bitmap->height - bitmap->top;
}
nPos += L; //前进L个字符
break;
}
}
nTagSkip = nLength; //解析完毕
nTagNext = nLength;

Draw:
if (m_xPencil.y + nYBearing + nMaxBottom > rect.Height())
goto Exit;
m_xPencil.y += nYBearing; //FreeType的钢笔位置

nPos = nTagPos;
while (nPos < nLength)
{
nPos = GetShort(lpText, &T, nPos);
nPos = GetShort(lpText, &L, nPos);
switch (T)
{
case TF_TRANSPARENT:
nPos = GetChar(lpText, (char *)&transparent, nPos);
break;
case TF_COLOR:
nPos = GetColor(lpText, &color, nPos);
break;
case TF_BKCOLOR:
nPos = GetColor(lpText, &bkcolor, nPos);
break;
case TF_WIDTH:
nPos = GetShort(lpText, (short *)&g_tDrawFS.tScalerRec.width, nPos);
break;
case TF_HEIGHT:
nPos = GetShort(lpText, (short *)&g_tDrawFS.tScalerRec.height, nPos);
break;
case TF_FAMILY:
nPos = GetFamily(lpText, g_tDrawFS.szFaceName, nPos, L);
UpdateFaceID(g_tDrawFS);
break;
case TF_STYLE:
nPos = GetChar(lpText, (char *)&g_tDrawFS.byStyle, nPos);
UpdateFaceID(g_tDrawFS);
break;
case TF_X_SPACE:
nPos = GetShort(lpText, (short *)&nXSpace, nPos);
break;
case TF_Y_SPACE:
nPos = GetShort(lpText, (short *)&nYSpace, nPos);
break;
case TF_TEXT:
//绘制一行所能容纳的字符
FTC_SBit bitmap;
for (int i = max(nPos, nTagCurr); i < nPos + L; i++)
{
if (i == nTagSkip)
goto Next;
if (lpText[i] == _T('\n'))
goto Next;

bitmap = GetBitmap(lpText[i], g_tDrawFS.tScalerRec);
AdjustBitmap(bitmap);

m_xPencil.x += nXSpace; //偏移字间距
if (!transparent)
{
//不透明时,填充背景色
FillGlyph(rect, g_shAdvance + nXSpace, nYBearing + nMaxBottom, nYBearing, bkcolor);
}
DrawGlyph(bitmap, transparent, color);
m_xPencil.x += g_shAdvance;
}
nPos += L; //前进L个字符
break;
}
}
Next:
m_xPencil.x = 0;
m_xPencil.y += nMaxBottom + nYSpace; //下一行的顶部

nTagPos = nTagNext;

if (!m_bMultiLine)
goto Exit;
}

Exit:
g_pZ2coo->Redraw(this);

return m_xPencil.y;
}
zhouyundong_2012
 
Posts: 148
Joined: 10 February 2012

Re: 3.77us Solver(2.8G CPU, TestCase:17Sodoku)

Postby zhouyundong_2012 » Fri Sep 02, 2016 11:06 am

#ifndef __MoveAnime_h__
#define __MoveAnime_h__

#include "Anime.h"

class CMoveAnime : public CAnime {
public:
CMoveAnime();
CMoveAnime(CPoint xSrcPoint, CPoint xDestPoint, int nFrame, int nPeriod, FN_AnimeEnd AnimeEnd = NULL, int *pParam = NULL);
virtual ~CMoveAnime();

public:
void SetSrcPoint(CPoint point);
void SetSrcPoint(int x, int y);
void SetDestPoint(CPoint point);
void SetDestPoint(int x, int y);

protected:
void SetUp();
void Update(int nDelta);

private:
CPoint m_xSrcPoint; //起点
CPoint m_xDestPoint; //终点

private:
float dx;
float dy;
};

inline void CMoveAnime::SetSrcPoint(CPoint point)
{
SetSrcPoint(point.x, point.y);
}

inline void CMoveAnime::SetDestPoint(CPoint point)
{
SetDestPoint(point.x, point.y);
}

#endif
zhouyundong_2012
 
Posts: 148
Joined: 10 February 2012

Re: 3.77us Solver(2.8G CPU, TestCase:17Sodoku)

Postby zhouyundong_2012 » Fri Sep 02, 2016 11:07 am

#include "StdAfx.h"

CFlickAnime::CFlickAnime() : CAnime()
{
}

CFlickAnime::CFlickAnime(int nFrame, int nShowPrd, int nHidePrd, bool bPriHide) : CAnime(nFrame, 0)
{
m_nShowPrd = nShowPrd;
m_nHidePrd = nHidePrd;
m_bPriHide = bPriHide;
}

CFlickAnime::~CFlickAnime()
{
}

void CFlickAnime::SetUp()
{
m_nPeriod = m_bPriHide ? m_nHidePrd : m_nShowPrd;
m_pAttach->Show(!m_bPriHide);
}

void CFlickAnime::Update(int nDelta)
{
bool bShow = m_pAttach->IsShow();

//显示/隐藏反相
m_nPeriod = bShow ? m_nHidePrd : m_nShowPrd;
m_pAttach->Show(!bShow);
}
zhouyundong_2012
 
Posts: 148
Joined: 10 February 2012

Re: 3.77us Solver(2.8G CPU, TestCase:17Sodoku)

Postby zhouyundong_2012 » Fri Sep 02, 2016 11:08 am

#ifndef __Bezier2D_h__
#define __Bezier2D_h__

#include "BezierBase.h"

class CBezier2D : public CBezierBase {
public:
CBezier2D(int nPoint, LPPOINT lpPoints);
virtual ~CBezier2D();

private:
void DeCasteljau(int ptx[], int pty[]);
bool CheckTermination(int ptx[], int pty[]);
};

#endif
zhouyundong_2012
 
Posts: 148
Joined: 10 February 2012

Re: 3.77us Solver(2.8G CPU, TestCase:17Sodoku)

Postby zhouyundong_2012 » Fri Sep 02, 2016 11:09 am

#ifndef __BezierBase_h__
#define __BezierBase_h__

#include "Curve.h"

#define MaxBezierDegree 16

class CBezierBase : public CCurve {
protected:
struct Span {
int ptx[MaxBezierDegree];
int pty[MaxBezierDegree];
};

public:
CBezierBase(int nCount, LPPOINT lpPoints);
virtual ~CBezierBase();

public:
virtual void Draw(CCanvas *pCanvas);

protected:
virtual void DeCasteljau(int ptx[], int pty[]) = 0;
virtual bool CheckTermination(int ptx[], int pty[]) = 0;

protected:
int m_nCount;
LPPOINT m_lpPoints;

protected:
Span m_span;
std::vector<Span> m_stack;
};

#endif
zhouyundong_2012
 
Posts: 148
Joined: 10 February 2012

Re: 3.77us Solver(2.8G CPU, TestCase:17Sodoku)

Postby zhouyundong_2012 » Fri Sep 02, 2016 11:09 am

#ifndef __BezierCurve_h__
#define __BezierCurve_h__

class CBezierCurve {
public:
CBezierCurve(int nDegree, int nCount, LPPOINT lpPoints, bool *lpFlags, COLORREF *lpColors, bool bClose = false);
~CBezierCurve();

public:
void Draw(CCanvas *pCanvas);

private:
void _Draw2D(CCanvas *pCanvas);
void _Draw3D(CCanvas *pCanvas);
void _DrawND(CCanvas *pCanvas);
void _UpdateCQ(int i);

private:
int m_nDegree;
int m_nCount;
LPPOINT m_lpPoints;
bool *m_lpFlags;
COLORREF *m_lpColors;
bool m_bClose;

private:
CPoint split_points[4];
CPoint tCenter;
CPoint tQuarter;
};

#endif
zhouyundong_2012
 
Posts: 148
Joined: 10 February 2012

Re: 3.77us Solver(2.8G CPU, TestCase:17Sodoku)

Postby zhouyundong_2012 » Fri Sep 02, 2016 11:09 am

#include "StdAfx.h"
#include "BezierND.h"

CBezierND::CBezierND(int nCount, LPPOINT lpPoints)
: CBezierBase(nCount, lpPoints)
{
}

CBezierND::~CBezierND()
{
}

void CBezierND::DeCasteljau(int ptx[], int pty[])
{
int pointx[MaxBezierDegree][MaxBezierDegree];
int pointy[MaxBezierDegree][MaxBezierDegree];

for (int i = 0; i < m_nCount; i++)
{
pointx[0][i] = ptx[i];
pointy[0][i] = pty[i];
}
//逐层计算分割点
for (int i = 1; i < m_nCount; i++)
{
for (int j = 0; j < m_nCount - i; j++)
{
pointx[i][j] = (pointx[i - 1][j] + pointx[i - 1][j + 1]) >> 1;
pointy[i][j] = (pointy[i - 1][j] + pointy[i - 1][j + 1]) >> 1;
}
}
//只压入右半部分
for (int i = 0; i < m_nCount; i++)
{
m_span.ptx[i] = pointx[m_nCount - i - 1][i];
m_span.pty[i] = pointy[m_nCount - i - 1][i];
}
m_stack.push_back(m_span);

//暂存左半部分
for (int i = 0; i < m_nCount; i++)
{
m_span.ptx[i] = pointx[i][0];
m_span.pty[i] = pointy[i][0];
}
}

bool CBezierND::CheckTermination(int ptx[], int pty[])
{
int dx = abs(ptx[m_nCount - 1] - ptx[0]);
int dy = abs(pty[m_nCount - 1] - pty[0]);

int epsilon = 65536;
if (dy > dx && dy < dx + dx || dy <= dx && dy + dy > dx)
epsilon <<= 2;

//max(|Xi - Xi-1|, |Yi - Yi-1|) <= epsilon
for (int i = 1; i < m_nCount; i++)
{
if (abs(ptx[i] - ptx[i - 1]) > epsilon || abs(pty[i] - pty[i - 1]) > epsilon)
return false;
}

return true;
}
zhouyundong_2012
 
Posts: 148
Joined: 10 February 2012

Re: 3.77us Solver(2.8G CPU, TestCase:17Sodoku)

Postby zhouyundong_2012 » Fri Sep 02, 2016 11:10 am

#ifndef __ChanBlend_h__
#define __ChanBlend_h__

class CChanBlend {
public:
~CChanBlend();

public: //Commutative Blend Modes
static byte Darken(byte bg, byte fg); //变暗模式
static byte Lighten(byte bg, byte fg); //变亮模式
static byte Multiply(byte bg, byte fg); //正片叠底模式
static byte LinearBurn(byte bg, byte fg); //线性加深模式
static byte LinearDodge(byte bg, byte fg); //线性减淡模式
static byte Screen(byte bg, byte fg); //滤色模式
static byte Difference(byte bg, byte fg); //差分模式
static byte Exclusion(byte bg, byte fg); //排除模式
static byte Average(byte bg, byte fg); //平均模式
static byte Negation(byte bg, byte fg); //负片模式
static byte Phoenix(byte bg, byte fg); //复兴模式
static byte Interpolation(byte bg, byte fg); //插值模式

public: //Non-commutative Blend Modes
static byte ColorBurn(byte bg, byte fg); //颜色加深模式
static byte ColorDodge(byte bg, byte fg); //颜色减淡模式
static byte ColorDark(byte bg, byte fg); //颜色加重模式
static byte Overlay(byte bg, byte fg); //叠加模式
static byte SoftLight(byte bg, byte fg); //柔光模式
static byte HardLight(byte bg, byte fg); //强光模式
static byte VividLight(byte bg, byte fg); //亮光模式
static byte LinearLight(byte bg, byte fg); //线性光模式
static byte PinLight(byte bg, byte fg); //点光模式
static byte HardMix(byte bg, byte fg); //实色混合模式
static byte Reflect(byte bg, byte fg); //反射模式
static byte Glow(byte bg, byte fg); //发光模式
static byte Freeze(byte bg, byte fg); //冷冻模式
static byte Heat(byte bg, byte fg); //加热模式

private:
static double *_TblCosine;
};

inline CChanBlend::~CChanBlend()
{
delete _TblCosine;
_TblCosine = NULL;
}

#endif
zhouyundong_2012
 
Posts: 148
Joined: 10 February 2012

Re: 3.77us Solver(2.8G CPU, TestCase:17Sodoku)

Postby zhouyundong_2012 » Fri Sep 02, 2016 11:10 am

#include "StdAfx.h"
#include "ChanBlend.h"

double *CChanBlend::_TblCosine = NULL;

byte CChanBlend::Darken(byte bg, byte fg)
{
return min(bg, fg);
}

byte CChanBlend::Lighten(byte bg, byte fg)
{
return max(bg, fg);
}

byte CChanBlend::Multiply(byte bg, byte fg)
{
return (bg * fg) >> 8;
}

byte CChanBlend::LinearBurn(byte bg, byte fg)
{
return max(bg + fg - 255, 0);
}

byte CChanBlend::LinearDodge(byte bg, byte fg)
{
return min(bg + fg, 255);
}

byte CChanBlend::Screen(byte bg, byte fg)
{
return 255 - ((255 - bg) * (255 - fg) >> 8);
}

byte CChanBlend::Difference(byte bg, byte fg)
{
return abs(bg - fg);
}

byte CChanBlend::Exclusion(byte bg, byte fg)
{
return bg + fg - (bg * fg >> 7);
}

byte CChanBlend::Average(byte bg, byte fg)
{
return (bg + fg) >> 1;
}

byte CChanBlend::Negation(byte bg, byte fg)
{
return 255 - abs(255 - bg - fg);
}

byte CChanBlend::Phoenix(byte bg, byte fg)
{
return min(bg, fg) - max(bg, fg) + 255;
}

byte CChanBlend::Interpolation(byte bg, byte fg)
{
if (_TblCosine == NULL)
{
_TblCosine = new double[256];
for (int i = 0; i < 255; i++)
_TblCosine[i] = cos(i * M_PI / 255.0);
}
return min(255, 128 - 64 * _TblCosine[bg] - 64 * _TblCosine[fg]);
}

byte CChanBlend::ColorBurn(byte bg, byte fg)
{
return fg == 0 ? 0 : max(0, 255 - ((255 - bg) << 8) / fg);
}

byte CChanBlend::ColorDodge(byte bg, byte fg)
{
return fg == 255 ? 255 : min(255, (bg << 8) / (255 - fg));
}

byte CChanBlend::ColorDark(byte bg, byte fg)
{
return min(255, (bg << 8) / (fg + 255));
}

byte CChanBlend::Overlay(byte bg, byte fg)
{
return bg <= 128 ? bg * fg >> 7 : 255 - ((255 - fg) * (255 - bg) >> 7);
}

byte CChanBlend::SoftLight(byte bg, byte fg)
{
return ((255 - bg) * bg * fg + bg * (65535 - (255 - bg) * ( 255 - fg))) >> 16;
}

byte CChanBlend::HardLight(byte bg, byte fg)
{
return fg > 127 ? (65535 - (255 - bg) * (255 - (fg - 127) * 2)) >> 8 : bg * fg >> 7;
}

byte CChanBlend::VividLight(byte bg, byte fg)
{
if (bg == 0 || bg == 255)
return bg;

return bg < 128 ? max(0, 255 - ((255 - fg) << 7) * bg) : min(255, (fg << 8) / (255 - (bg - 128) * 2));
}

byte CChanBlend::LinearLight(byte bg, byte fg)
{
return bg < 128 ? max(0, (bg << 1) - fg) : min(255, ((bg - 128) << 1) + fg);
}

byte CChanBlend::PinLight(byte bg, byte fg)
{
return fg < 128 ? min(fg << 1, bg) : max((fg - 128) << 1, bg);
}

byte CChanBlend::HardMix(byte bg, byte fg)
{
return bg + fg < 255 ? 0 : 255;
}

byte CChanBlend::Reflect(byte bg, byte fg)
{
return fg == 255 ? fg : min(255, bg * bg / (255 - fg));
}

byte CChanBlend::Glow(byte bg, byte fg)
{
return bg == 255 ? bg : min(255, fg * fg / (255 - bg));
}

byte CChanBlend::Freeze(byte bg, byte fg)
{
return fg == 0 ? 0 : max(0, 255 - (255 - bg) * (255 - bg) / fg);
}

byte CChanBlend::Heat(byte bg, byte fg)
{
return bg == 0 ? 0 : max(0, 255 - (255 - fg) * (255 - fg) / bg);
}
zhouyundong_2012
 
Posts: 148
Joined: 10 February 2012

Re: 3.77us Solver(2.8G CPU, TestCase:17Sodoku)

Postby zhouyundong_2012 » Fri Sep 02, 2016 11:10 am

/******************************************************************************
*
* 垂直渐变的算法和斜渐变的完全不同,必须单独处理;
* 以贴图的方式填充渐变区域很高效,
* 但是当渐变区间跨度非常大时,只能采用逐象素绘制。
* 权衡两者,取贴图的最大长度为4096个象素是合适的。
*
******************************************************************************/
#include "StdAfx.h"
#include "GradientFill.h"

#define MaxSpriteLength 4096

CGradientFill::CGradientFill() : CFill()
{
m_pGradient = new CImage(MaxSpriteLength, 1);
m_pSprite = new CSprite(m_pGradient, CPoint(), CSize(), 0);
}

CGradientFill::~CGradientFill()
{
delete m_pGradient;
delete m_pSprite;
}

void CGradientFill::InitFill()
{
int dx = m_xOrigin2.x - m_xOrigin1.x;
int dy = m_xOrigin2.y - m_xOrigin1.y;

//渐变跨度
m_nLength = dx == 0 ? dy : dx + dy * dy / dx;
m_nLength = abs(m_nLength);

int b1 = GetBValue(m_color);
int g1 = GetGValue(m_color);
int r1 = GetRValue(m_color);

//线性颜色渐变分量
m_db = (float)(GetBValue(m_bkcolor) - b1) / m_nLength;
m_dg = (float)(GetGValue(m_bkcolor) - g1) / m_nLength;
m_dr = (float)(GetRValue(m_bkcolor) - r1) / m_nLength;

//垂直和渐变跨度小时构造渐变贴图
if (m_nLength <= MaxSpriteLength)
{
//斜渐变时左到右为1 垂直渐变时上到下为1
int uxuy = dx > 0 || dx == 0 && dy > 0 ? 1 : -1;
int nOffset = uxuy == 1 ? 0 : m_nLength - 1;

//两个方向统一处理
for (int i = 0; i < m_nLength; i++, nOffset += uxuy)
{
int b = b1 + m_db * nOffset;
int g = g1 + m_dg * nOffset;
int r = r1 + m_dr * nOffset;

m_pGradient->SetPixel(i, 0, BGRA(b, g, r, 255));
}
}
}

void CGradientFill::FillLine(int x1, int x2, int y)
{
//垂直渐变必须单独处理
m_xOrigin1.x == m_xOrigin2.x ? _LineVert(x1, x2, y) : _LineLean(x1, x2, y);
}

void CGradientFill::_LineVert(int x1, int x2, int y)
{
//渐变区间上下界限
int minY = min(m_xOrigin1.y, m_xOrigin2.y);
int maxY = max(m_xOrigin1.y, m_xOrigin2.y);

//获得不同区间的颜色
COLORREF color;
if (y < minY)
color = m_xOrigin2.y > m_xOrigin1.y ? m_color : m_bkcolor;
else if (y >= maxY)
color = m_xOrigin2.y > m_xOrigin1.y ? m_bkcolor : m_color;
else
color = m_pGradient->GetPixel(y - minY, 0);

m_pImage->FillLine(x1, x2, y, color);
}

void CGradientFill::_LineLean(int x1, int x2, int y)
{
int dx = m_xOrigin2.x - m_xOrigin1.x;
int dy = m_xOrigin2.y - m_xOrigin1.y;

//和斜渐变线垂直的两直线与水平扫描线的左右交点
int minX = (float)dy / dx * (m_xOrigin1.y - y) + m_xOrigin1.x;
if (dx < 0)
minX -= m_nLength;
int maxX = minX + m_nLength;

//绘制左边颜色
if (x1 < minX)
m_pImage->FillLine(x1, min(minX, x2), y, dx > 0 ? m_color : m_bkcolor);

//绘制右边颜色
if (x2 >= maxX)
m_pImage->FillLine(max(maxX, x1), x2, y, dx > 0 ? m_bkcolor : m_color);

//绘制渐变区间
Span span;
span.nStart = max(x1, minX);
span.nEnd = min(x2, maxX);
span.nLength = span.nEnd - span.nStart;
span.y = y;
if (span.nLength > 0)
{
//以贴图的方式高效,斜率很大时只能采用逐象素绘制
int nSrcPos = max(-minX, 0);
m_nLength <= MaxSpriteLength ? _LineBySprite(span, nSrcPos) : _LineByPixel(span, nSrcPos);
}
}

void CGradientFill::_LineBySprite(const Span& span, int nSrcPos)
{
m_pSprite->SetSrcPos(nSrcPos, 0);
m_pSprite->SetDrawPos(span.nStart, span.y);
m_pSprite->SetSize(span.nLength, 1);

m_pSprite->Draw(m_pImage);
}

void CGradientFill::_LineByPixel(const Span& span, int nSrcPos)
{
int b1 = GetBValue(m_color);
int g1 = GetGValue(m_color);
int r1 = GetRValue(m_color);

//斜渐变:左到右为1,右到左为-1
int ux = m_xOrigin1.x < m_xOrigin2.x ? 1 : -1;
int nOffset = m_xOrigin1.x < m_xOrigin2.x ? nSrcPos : m_nLength - nSrcPos - 1;

//两个方向统一处理
for (int i = 0; i < span.nLength; i++, nOffset += ux)
{
int b = b1 + m_db * nOffset;
int g = g1 + m_dg * nOffset;
int r = r1 + m_dr * nOffset;

m_pImage->SetPixel(span.nStart + i, span.y, BGRA(b, g, r, 255));
}
}
zhouyundong_2012
 
Posts: 148
Joined: 10 February 2012

Re: 3.77us Solver(2.8G CPU, TestCase:17Sodoku)

Postby zhouyundong_2012 » Fri Sep 02, 2016 11:11 am

#include "StdAfx.h"
#include "HatchFill.h"

CHatchFill::CHatchFill()
{
m_xOrigin.x = 0;
m_xOrigin.y = 0;

//贴图扩展为64 * 8,以提高绘制效率
m_pHatch = new CImage(64, 8);
m_pSprite = new CSprite(m_pHatch, CPoint(), CSize(), 0);
}

CHatchFill::~CHatchFill()
{
delete m_pHatch;
delete m_pSprite;
}

void CHatchFill::SetStyle(int nStyle)
{
switch (nStyle)
{
case HFS_HORIZONTAL:
m_nHatchBitmap = 0x00000000000000FF;
break;
case HFS_VERTICAL:
m_nHatchBitmap = 0x0101010101010101;
break;
case HFS_FDIAGONAL:
m_nHatchBitmap = 0x8040201008040201;
break;
case HFS_BDIAGONAL:
m_nHatchBitmap = 0x0102040810204080;
break;
case HFS_CROSS:
m_nHatchBitmap = 0x01010101010101FF;
break;
case HFS_DIAGCROSS:
m_nHatchBitmap = 0x8142241818244281;
break;
default:
m_nHatchBitmap = 0;
}
}

void CHatchFill::InitFill()
{
//构造画刷图象
unsigned __int64 nBitMask = 0x8000000000000000;
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
m_pHatch->SetPixel(j, i, m_nHatchBitmap & nBitMask ? m_color : m_bkcolor);
nBitMask >>= 1;
}
}

//以下是将贴图复制7份,以提高绘制效率
int nBytesPerGroup = m_pHatch->BytesPerPixel() * 8;
for (int i = 0; i < 8; i++)
{
for (int j = 1; j < 8; j++)
{
//将贴图复制7份
memcpy(m_pHatch->GetBits(j << 3, i), m_pHatch->GetBits(0, i), nBytesPerGroup);
}
}
}

void CHatchFill::FillLine(int x1, int x2, int y)
{
//第一段的源位置
CPoint xSrcPos;
xSrcPos.x = (x1 - m_xOrigin.x) & 0x07;
xSrcPos.y = (y - m_xOrigin.y) & 0x07;

//总长度,已绘制长度,逐段长度
int nLength = x2 - x1;
int nDrawLen = 0;
int nTempLen = min(64 - xSrcPos.x, nLength);
do
{
m_pSprite->SetSrcPos(xSrcPos);
m_pSprite->SetDrawPos(x1 + nDrawLen, y);
m_pSprite->SetSize(nTempLen, 1);
m_pSprite->Draw(m_pImage);

//更新长度和源位置
nDrawLen += nTempLen;
nTempLen = min(nLength - nDrawLen, 64);

xSrcPos.x = 0;
} while (nDrawLen < nLength);
}
zhouyundong_2012
 
Posts: 148
Joined: 10 February 2012

Re: 3.77us Solver(2.8G CPU, TestCase:17Sodoku)

Postby zhouyundong_2012 » Fri Sep 02, 2016 11:11 am

#include "StdAfx.h"
#include "FrostedFilter.h"

CFrostedFilter::CFrostedFilter(int nMinRadius, int nMaxRadius, int nSamples)
{
m_nMinRadius = nMinRadius;
m_nMaxRadius = nMaxRadius;
m_nSamples = nSamples;
}

CFrostedFilter::~CFrostedFilter()
{
}

void CFrostedFilter::Filter(CImage *pImage, const CRect& rect)
{
//环形域内的随机样本
COLORREF *pSamples = new COLORREF[m_nSamples];

CImage *pTemp = new CImage(pImage->Width(), pImage->Height());
for (int y = rect.top; y < rect.bottom; y++)
{
for (int x = rect.left; x < rect.right; x++)
{
for (int s = 0; s < m_nSamples; s++)
{
double distance = RandDbl(m_nMinRadius, m_nMaxRadius); //随机离散距离
double angle = RandDbl(0, 1) * M_PI * 2; //随机偏转角度

int sampx = x + cos(angle) * distance; //水平采样点坐标
int sampy = y + sin(angle) * distance; //垂直采样点坐标
sampx = min(max(0, sampx), pImage->Width() - 1);
sampy = min(max(0, sampy), pImage->Height() - 1);

pSamples[s] = pImage->GetPixel(sampx, sampy);
}
COLORREF color = BlendColors(pSamples, m_nSamples);
pTemp->SetPixel(x, y, color);
}
}
pImage->Copy(pTemp, rect);
delete pTemp;

delete pSamples;
}

COLORREF CFrostedFilter::BlendColors(COLORREF colors[], int nLength)
{
int bsum = 0, gsum = 0, rsum = 0, asum = 0;
//进行Alpha混合模糊
for (int i = 0; i < nLength; i++)
{
asum += GetAValue(colors[i]);
bsum += GetAValue(colors[i]) * GetBValue(colors[i]);
gsum += GetAValue(colors[i]) * GetGValue(colors[i]);
rsum += GetAValue(colors[i]) * GetRValue(colors[i]);
}
//混合结果为透明
if (asum == 0)
return BGRA(0, 0, 0, 0);

return BGRA(bsum / asum, gsum / asum, rsum / asum, asum / nLength);
}
zhouyundong_2012
 
Posts: 148
Joined: 10 February 2012

PreviousNext

Return to Software