绘图
绘图的结果如下:
绘图部分主要使用了 Bitmap、Graphics
具体的函数是 MakeMap
入参说明
string bg : 背景图
Rectangle rect :绘图区域
int row_count :行数
int col_count :列数
string fn :保存到的文件
代码如下:
public void MakeMap(string bg ,Rectangle rect ,int row_count,int col_count ,string fn)
{
Bitmap bmp = new Bitmap(bg);
Graphics g = Graphics.FromImage(bmp);
SHIUtils u = new SHIUtils();
u.init_data(data);
int line_w = 1;
int cell_w = (rect.Width - line_w*(col_count+1)) / col_count;
int cell_h = (rect.Height - line_w * (row_count + 1)) / row_count;
int w = line_w * (col_count + 1) + cell_w * col_count;
int h = line_w * (row_count + 1) + cell_h * row_count;
int x0 = rect.X + (rect.Width - w) / 2;
int y0 = rect.Y + (rect.Height - h ) / 2;
Pen pen = new Pen(Color.FromArgb(196, 196, 196));
for (int col = 0; col <= col_count; col++)
{
int x = x0 + (line_w + cell_w) * col;
g.DrawLine(pen, x, y0, x, y0 + h - line_w);
}
for (int row = 0; row <= row_count; row++)
{
int y = y0 + (line_w + cell_h) * row;
g.DrawLine(pen, x0, y, x0 + w - line_w, y);
}
// g.SmoothingMode = SmoothingMode.HighQuality;
g.TextRenderingHint = TextRenderingHint.AntiAlias;
Font font = new Font("汉呈波波浓墨行楷", cell_w*90/100, FontStyle.Regular);
SolidBrush brush = new SolidBrush(Color.Black);
SolidBrush brush_cell = new SolidBrush(Color.FromArgb(225, 225, 225));
StringFormat sf = new StringFormat();
SHIMap map = u.make_map(col_count, row_count);
for (int col = 0; col < col_count; col++)
for (int row = 0; row < row_count; row++)
{
MapHole cell= map.map[col, row];
if (cell.chr != ' ')
{
int x = x0 + (line_w + cell_w) * col + line_w;
int y = y0 + (line_w + cell_h) * row + line_w;
g.FillRectangle(brush_cell, new Rectangle(x , y , cell_w , cell_h));
string s = cell.chr.ToString();
if (cell.sentence_list.Count == 2)
s = "?";
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
g.DrawString(s, font, brush, new Rectangle(x, y, cell_w, cell_h), sf);
}
}
g.Dispose();
bmp.Save(fn, ImageFormat.Png);
bmp.Dispose();
}
古诗填字
绘图的内容由SHIUtils生成。
SHIMap map = u.make_map(col_count, row_count);
函数中使用了随机数,每次调用生成的内容都不一样,具体的代码如下:
public class SHIUtils
{
public static Char Char_comma = ',';
public static Char Char_period = '。';
public static Char Char_period_1 = '!';
public static Char Char_period_2 = '?';
public static Char Char_period_3 = '、';
public static Char Char_period_4 = ';';
public static Char Char_period_5 = ':';
public static Char Char_period_6 = '\r';
public static Char Char_period_7 = '\n';
public Random rd = new Random(Guid.NewGuid().GetHashCode());
public void clear()
{
}
private SHIData _data = null;
private Dictionary<char, int> _char_dict = new Dictionary<char, int>();
private Dictionary<int, SHI> _shi_dict = new Dictionary<int, SHI>();
private Dictionary<int, Sentence> _sentence_dict= new Dictionary<int, Sentence>();
private Dictionary<char, Dictionary<int, Sentence>> _sentence_index = new Dictionary<char, Dictionary<int, Sentence>>();
private Dictionary<char, List<Sentence>> _sentence_index_list = new Dictionary<char, List< Sentence>>();
private Dictionary<int, Dictionary<int, Sentence>> _sentence_index_len = new Dictionary<int, Dictionary<int, Sentence>>();
private Dictionary<int, List< Sentence>> _sentence_index_len_list = new Dictionary<int, List<Sentence>>();
public Dictionary<int, List<Sentence>> get_sentence_index_len_list()
{
return _sentence_index_len_list;
}
public Dictionary<int, SHI> get_shi_dict()
{
return _shi_dict;
}
private void do_init()
{
clear();
make_char_dict();
make_sentence_list();
}
private void make_char_dict()
{
_char_dict.Clear();
foreach (SHI i in _data.Items)
{
foreach (Char ch in i.contson)
{
if (_char_dict.ContainsKey(ch))
continue;
_char_dict[ch] = _char_dict.Count;
}
}
}
private void make_sentence_list()
{
_shi_dict.Clear();
_sentence_dict.Clear();
_sentence_index.Clear();
_sentence_index_list.Clear();
_sentence_index_len.Clear();
_sentence_index_len_list.Clear();
foreach (SHI i in _data.Items)
{
_shi_dict[i.id] = i;
Sentence s = null;
int idx = 0;
foreach (Char ch in i.contson)
{
if (ch == '\r')
continue;
if (ch == '\n')
continue;
if (s == null)
{
s = new Sentence();
s.shi_id = i.id;
s.idx = idx;
s.id = s.shi_id * 1000 + idx;
idx++;
_sentence_dict[s.id]=s;
}
if ((ch == Char_comma) || (ch == Char_period) || (ch == Char_period_1) || (ch == Char_period_2) || (ch == Char_period_3) || (ch == Char_period_4)||(ch==Char_period_5) || (ch == Char_period_6) || (ch == Char_period_7))
{
s.chr_end = ch;
foreach (Char ch_s in s.chrlist)
{
Dictionary<int, Sentence> ls = null;
if (!_sentence_index.TryGetValue(ch_s,out ls))
{
ls = new Dictionary<int, Sentence>();
_sentence_index[ch_s] = ls;
}
if (! ls.ContainsKey(s.id))
ls[s.id] =s;
}
{
Dictionary<int, Sentence> ls = null;
if (!_sentence_index_len.TryGetValue(s.chrlist.Count,out ls))
{
ls = new Dictionary<int, Sentence>();
_sentence_index_len[s.chrlist.Count] = ls;
}
if (!ls.ContainsKey(s.id))
{
ls[s.id] = s;
}
}
s = null;
}
else
{
s.chrlist.Add(ch);
s.txt = s.txt + ch;
}
}
}
foreach(KeyValuePair<int, Dictionary<int, Sentence>> kv in _sentence_index_len)
{
List<Sentence> ls = new List<Sentence>();
_sentence_index_len_list[kv.Key] = ls;
foreach (KeyValuePair<int, Sentence> kv2 in kv.Value)
{
ls.Add(kv2.Value);
}
}
foreach (KeyValuePair<Char, Dictionary<int, Sentence>> kv in _sentence_index)
{
List<Sentence> ls = new List<Sentence>();
_sentence_index_list[kv.Key] = ls;
foreach (KeyValuePair<int, Sentence> kv2 in kv.Value)
{
ls.Add(kv2.Value);
}
}
}
public void init_data(SHIData data)
{
_data = data;
do_init();
}
public void load()
{
}
public Sentence get_sentence_rand_by_len(int len)
{
List<Sentence> ls = new List<Sentence>();
if (_sentence_index_len_list.TryGetValue(len, out ls))
{
int i = rd.Next(ls.Count);
return ls[i];
}
else
{
return null;
}
}
private int fill_map_with_hole_list(SHIMap sm,List<MapHole> hole_list ,int step)
{
int c = 0;
foreach (MapHole hole in hole_list )
{
Char ch = hole.chr;
List<Sentence> ls = null;
if ( _sentence_index_list.TryGetValue(ch,out ls))
{
int idx_0 = rd.Next(ls.Count);
for (int i=0;i<ls.Count-1;i++)
{
int idx = (i + idx_0) % (ls.Count);
Sentence s = ls[idx];
if (s.chrlist.Count < _data.min_s_chr_cnt)
continue;
if (sm.sentence_list.ContainsKey(s.txt))
continue;
int pos = s.chrlist.IndexOf(ch);
if (pos>=0)
{
if ((i % 2) == 0)
{
int x1 = hole.x - pos;
int y1 = hole.y;
if (sm.can_fill_horizontal(s, x1, y1))
{
sm.fill_horizontal(s, x1, y1, step);
c++;
}
} else
{
int x1 = hole.x ;
int y1 = hole.y - pos;
if (sm.can_fill_vertical(s, x1, y1))
{
sm.fill_vertical(s, x1, y1, step);
c++;
}
}
}
}
}
}
return c;
}
private void fill_map(SHIMap sm)
{
Sentence s0 = get_sentence_rand_by_len(7);
if (s0==null)
s0 = get_sentence_rand_by_len(5);
if (s0 == null)
s0 = get_sentence_rand_by_len(4);
int x0 = (sm.width - s0.chrlist.Count) / 2;
int y0 = (sm.height - 2) / 2;
// int x0 = 0;
// int y0 = 0;
if (!sm.can_fill_horizontal(s0, x0, y0))
return;
sm.fill_horizontal(s0, x0, y0, 1);
for (int step=2; step < 1000; step++)
{
int c = 0;
for (int i = sm.step_list.Count-1;i>=0;i--)
{
if (i <= sm.step_list[i].step - 2)
break;
c = c + fill_map_with_hole_list(sm, sm.step_list[i].hole_list, step);
}
if (c<=0)
{
break;
}
}
}
public SHIMap make_map(int width, int height)
{
SHIMap sm = new SHIMap();
sm.init_map(width, height);
fill_map(sm);
return sm;
}
}
}
例图