C# 绘图及古诗填字

绘图

绘图的结果如下:

绘图部分主要使用了 Bitmap、Graphics

具体的函数是 MakeMap

入参说明

string bg : 背景图

Rectangle rect :绘图区域

int row_count :行数

int col_count :列数

string fn :保存到的文件

代码如下:

cs 复制代码
        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);

函数中使用了随机数,每次调用生成的内容都不一样,具体的代码如下:

cs 复制代码
 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;
        }
    }
}

例图

相关推荐
军训猫猫头13 分钟前
20.抽卡只有金,带保底(WPF) C#
ui·c#·wpf
一个处女座的程序猿O(∩_∩)O1 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js
hackeroink4 小时前
【2024版】最新推荐好用的XSS漏洞扫描利用工具_xss扫描工具
前端·xss
迷雾漫步者6 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-6 小时前
验证码机制
前端·后端
燃先生._.7 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖8 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
m0_748235248 小时前
前端实现获取后端返回的文件流并下载
前端·状态模式
m0_748240259 小时前
前端如何检测用户登录状态是否过期
前端