1

梦幻西游手游炼药信息采集系统

一、初衷

本文不是软文!!!本文不是软文!!!本文不是软文!!!文章开始重要的事情说三遍!!!
初中时玩一款网易的游戏叫《梦幻西游》,前两天看朋友在玩《梦幻西游手游》,于是下下来缅怀一下,众所周知,玩梦幻是需要人民币的,像我等穷屌一分钱不花的在游戏里是寸步难行的,于是在里面找寻商机,囤货赚差价这种高级的玩不来,就学了个中医药理,俗称炼药。
图片描述
炼药是什么机理呢,我有八种原材料,其中初级的四种,高级的四种,挑选其中四个作为炼药的配方,可以重复添加,然后进行炼制,炼制的结果有两种,成功和失败,失败就是炼制出金创药,成功就会炼制出另外四种三级药,炼制出来的三级药也根据种类和品质的不同而卖出去的价钱不同。但是只要炼制成功就有钱赚,于是问题就简化为了求哪四个二药组合起来的配方使得到三级药的成功率最高!
当然网上的攻略都不靠谱,也没有大量的实践佐证,于是身为程序猿就在想能不能收集大量的数据然后通过数据挖掘的算法或者BP神经网络来分析一下最优配方,哪怕算法行不通,最后用统计学的方式来看概率也行。
于是开始慢慢的记录每次炼药的数据,开始是这样的,放在印象笔记中:
图片描述
直到昨天和小伙伴商量算法的事儿,觉得这样录入数据效率太低了,也不直观,后期也不方便用,于是就想到先写个网站进行数据采集,等着可以放到公网上让大家一块儿来增加数据。于是问题就成了写个网站录入数据,又不想写传统的LAMP,于是就想用最近学到的NodeJS+Express+Bower+Bootstrap+MongoDB+Mongoose,好,开撸。

二、环境搭建

先装MongoDB,有了XCodeGhost的教训,大家记得要去官网哦,https://www.mongodb.org/
再装数据库的可视化工具,我可不是用cmd的DBA,是弱鸡就不要装逼,挑了款大家说的多的,Robomongo,http://robomongo.org/
再装Node.js,https://nodejs.org/
由于Node.js需要用命令行,然而win的CMD 不给力,然后就装个扩展的cmd,正好GitHub的win版本带着GitHub Shell灰常好用,于是再下个win的GitHub,https://desktop.github.com/
装完啦,先开始访问一下数据库能不能行。

三、数据库

1.开启服务

首先创建数据库文件存放的目录,否则服务不能启动,我是放在了E:\mongodb\data\db
然后进入mongodb的bin目录下,按住shift右键,在此处打开命令行,呼出cmd
mongod --dbpath "E:\mongodb\data\db" --logpath "E:\mongodb\data\log\MongoDB.log" --install --serviceName "MongoDB"
log的目录应该能自动创建,不能创建的话创建一下,这种是把mongodb作为win服务的形式,个人比较喜欢,设为手动服务后省的以后每次敲命令。

2.连接数据库

启动robomongo,给连接起个名字,其他的默认就能连接上,连上之后是这个样子的,下面那个是我后来建立的:
图片描述
好了,数据库的内容先告一段落。

四、Express

开始写前后端啦,先下载Express,进到git shell里
npm install express -g -g是将express安装到全局
然后坑就来啦,之前创建express项目都是express app但是现在会报错,找不到命令,那是因为XXXX,解决方式就是再下载个插件
npm install express-generator -g
然后就可以快乐的 express medicine 啦,medicine是我的项目名称
然后就呼啦生成了一堆目录,最后会有提示,让你
图片描述
这个过程就是把项目用到的依赖项下载好,然后把端口和服务打开,于是再浏览器输入localhost:3000,以下就是刚生成的初始页面
图片描述
顺道把我的文件目录附上吧
图片描述

五、Bower+Bootstrap

直接改index页面就好,目前就一个功能,就是选完一堆材料之后用ajax传到后台
由于要用到Bootstrap,于是就用bower来管理
npm install bower -g
bower install bootstrap
这样会顺道把jquery下载下来,由于后边也会用到,就省的下载了
express的默认模板引擎用的是Jade,语法不懂诸位看官自己看去
为了能直接引用bower目录下的文件,于是在app.js中添加路径声明
app.use(express.static(path.join(__dirname, 'bower_components')));
在layout.jade模板中引用bootstrap和jquery和我自己的js文件change

doctype html
html
  head
    title= title
    link(rel='stylesheet', href='/stylesheets/style.css')
    link(rel='stylesheet', href='/bootstrap/dist/css/bootstrap.min.css')
  body
    block content
    script(src='jquery/dist/jquery.min.js')
    script(src='/bootstrap/dist/js/bootstrap.min.js')
    script(src='/javascripts/change.js')

jade的缩进也是坑,所以我习惯在sublime中做如下配置
"tab_size": 2,
"translate_tabs_to_spaces": true
然后就可以在index.jade中写界面啦,刚开始肯定非常丑啦,一切从简,以后再改

extends layout

block content
  .container
    .h1 炼药信息采集
    hr
    .h2 请选择二药:
    .btn-group
      button.btn.btn-default.two 血色茶花
      button.btn.btn-default.two 仙狐延
      button.btn.btn-default.two 鹿茸
      button.btn.btn-default.two 麝香
    p
    .btn-group
      button.btn.btn-default.two 火凤之睛
      button.btn.btn-default.two 孔雀红
      button.btn.btn-default.two 血珊瑚
      button.btn.btn-default.two 凤凰尾
    hr
    .h2 配方:
    p
    .btn-group
      button.btn.btn-default.mat 五龙丹1
      button.btn.btn-default.mat 五龙丹2
    p
    .btn-group
      button.btn.btn-default.mat 五龙丹3
      button.btn.btn-default.mat 五龙丹4
    hr
    .h2 请选择三药及品质:
    p
    select.form-control#three
      option 金疮药
      option 定神香
      option 五龙丹
      option 金香玉
      option 九转还魂丹
    p
    .form-group
      input.form-control#quality(type='text',placeholder='输入品质')
    hr
    button.btn.btn-default#sub 提交

又是一个坑,之前也没用过bootstrap,下拉菜单和下拉选择框傻傻分不清楚,开始竟然写了个dropdown死活样式不对。
写完基本的前端页面后,预览一下是这个样子的:
图片描述
前端页面就是 结构(HTML)+样式(CSS)+行为(JavaScript)嘛,前两个搞定了,下面开始行为

六、JavaScript部分

想法是,定义一个四个元素的数组,点击上面8中原料的时候执行数组的尾插入,头抛掉,也就是只能放四个,然后在页面中显示出来,炼药完之后选择生成的三药,然后输入品质,然后点击提交通过ajax发送到后台
这是change.js的内容

$(function(){
  var materias = [0,0,0,0];
  function matInsert(type) {
    for(i = 0;i<3;i++){
      materias[i] = materias[i+1];
    }
    materias[3] = type;
  };
  var two = $('.two');
  var len = two.length;
  for (j = 0; j < len; j++) {
    two[j].index = j;
  }
  two.click(function(){
    matInsert(this.index);
    console.log(materias);
    var mat = $('.mat');
    for(m = 0; m < 3; m++){
      mat.eq(m).html(mat.eq(m+1).html());
    }
    mat.eq(3).html($(this).html());
  });
  $('#sub').click(function(){
    $.ajax({
      type: 'POST',
      url: '/change',
      data: JSON.stringify({"materias":materias,"three":$('#three').val(),"quality":$('#quality').val()}),
      success: function(data) { },
      contentType: "application/json",
      dataType: 'text'
    });
  });
});

js的思路上面说了,现在就来说说这个坑,注意我用的是$.ajax不是$.post,因为必须得进行一些参数控制,向后台发送的必须是标准JSON格式的,否则后端的解析会有问题
主要是
data: JSON.stringify({"materias":materias,"three":$('#three').val(),"quality":$('#quality').val()}),
contentType: "application/json",
这两句,一定要注意,在这里踩了大坑了,大坑!
具体原因请戳这个 https://cnodejs.org/topic/54929c5561491ead0cc7bff2
然后数据就发向后台了,开始写路由和接受的函数

七、路由及逻辑

app.js中加上
var change = require('./routes/change');
然后routers文件夹下的逻辑change.js

var express = require('express');
var router = express.Router();
var Medicine = require('./../models/Medicine.js');

router.post('/', function(req, res, next) {

  Medicine.save(req.body, function(err){
    if(err) {
      res.send({'success':false,'err':err});
    } else {
      res.send({'success':true});

    }
  });
});

module.exports = router;

Medicine.save这里是存数据的方法,后面说,他们说我这个req.body这样写不好,我暂时还不会其他的,先用着

八、DAO

创建一个文件夹models,新建连接数据库的文件mongodb.js

var mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/medicine');

exports.mongoose = mongoose;

medicine这个数据不存在的话会自动创建,所以数据库那边不用管

新增记录到数据库的方法在这里,网上找代码凑得,能用,后边再慢慢理解慢慢优化Medicine.js

var mongodb = require('./mongodb');

var Schema = mongodb.mongoose.Schema;
var MedicineSchema = new Schema({
    materias : Array,
    three : String,
    quality : Number,
    createDate : {type : Date, default : Date.now}
});
var Medicine = mongodb.mongoose.model('Medicine', MedicineSchema);
var MedicineDAO = function(){};

MedicineDAO.prototype.save = function(obj, callback) {
    var instance = new Medicine(obj);
    instance.save(function(err){
        callback(err);
    });
};

module.exports = new MedicineDAO();

然后就大功告成喽~
插入条数据试试,robo里能看到
图片描述
收工!

九、总结

从有想法到做出来差不多历时一天半吧,由于这些框架全都是第一次用,所以踩坑不少,分享出来只是为了和大家交流以及刚做这个的少踩坑。
目前太简陋,只是做了一个数据记录功能,接下来还要扩展,增加很多细节,比如提交的loading效果,把文字全都换成图片,用个雪碧图,增加撤销功能,用grunt或者gulp管理,然后还需要一个数据显示功能,最后还要用Echart把结果用折线和饼图展示出来,方便直观的看到走势,还有一部分计算将目前成功率最高的进行排行,数据挖掘的算法部分还需要跟小伙伴商量。
后天开题答辩了,报告没整完PPT 做,答完再继续做。预祝大家游戏玩的开心,代码写的顺心。
先把这第一版放出来,小弟初学此道,还请大家批评指正!
https://github.com/ifibercc/mhMedicine

如果文中有对“广州网易计算机系统有限公司”侵权的行为,请联系我,立马删文。
ifibercc@gmail.com


景初
730 声望30 粉丝

前端 / 数据挖掘 / CCIE / 炉石